<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title> </title><link>http://www.openlogic.com/wazi/</link><description>OpenLogic - Wazi</description><ttl>60</ttl><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/openlogic/wazi" /><feedburner:info uri="openlogic/wazi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><comments>http://www.openlogic.com/wazi/bid/291730/Use-Perl-to-enhance-ModSecurity#Comments</comments><slash:comments>0</slash:comments><title>Use Perl to enhance ModSecurity</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/gJcV_OlfzCc/Use-Perl-to-enhance-ModSecurity</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/modsecurity"&gt;ModSecurity&lt;/a&gt; is the most popular open source web application firewall. Its built-in, basic functionality simply blocks a client's request if it matches a security rule. However, you can extend ModSecurity in various ways, including through your own custom &lt;a href="http://olex.openlogic.com/packages/perl"&gt;Perl&lt;/a&gt; scripts. Let's see how.&lt;/p&gt;
&lt;p&gt;I'm going to assume you have already installed and configured ModSecurity. If not, read how to &lt;a href="http://www.openlogic.com/wazi/bid/188075/Protect-And-Audit-Your-Web-Server-With-ModSecurity"&gt;Protect and audit your web server with ModSecurity&lt;/a&gt;. I'll also create a script you can use, and make it as simple as possible so that you can understand the logic and rewrite the code in any programming language if you so choose.&lt;/p&gt;
&lt;h3&gt;How to extract the needed information&lt;/h3&gt;
&lt;p&gt;By default, any request that triggers a ModSecurity rule is logged in the Apache's error log (/var/log/httpd/error_log). An example ModSecurity entry looks like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[Mon May 06 09:16:12 2013] [error] [client 10.0.0.1] ModSecurity: Warning. Operator LT matched 5 at TX:inbound_anomaly_score. [file "/etc/httpd/conf/crs/modsecurity_crs_60_correlation.conf"] [line "33"] [id "981203"] [msg "Inbound Anomaly Score (Total Inbound Score: 2, SQLi=, XSS=): Request Missing an Accept Header"] [hostname "www.example.org"] [uri "/index.php"] [unique_id "BOlcOH8AAAEAABlxPboAAAAJ"]&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This entry provides a lot of information, such as time of request (Mon May 06 09:16:12 2013), remote client's IP address (client 10.0.0.1), and the triggered ModSecurity rule ID (id "981203"). You can focus on this information and extract it with a &lt;a href="http://www.regular-expressions.info/"&gt;regular expression&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A good regular expression for this purpose is&lt;/p&gt;
&lt;pre&gt;\[ $date .*\[client ([0-9|\.]*)\] ModSecurity.*\[id "([0-9]{6})"\]&lt;/pre&gt;
&lt;p&gt;How do you interpret that? First, one variable is used – date. It determines the time range for which information will be extracted. It is in the format Day Month Day-Of-Month Hour:Minute:Seconds Year. You don't have to specify the full date; use only the part you want and the rest is matched automatically. For example, if you need information only for one day, you should specify &lt;code&gt;Mon May 06&lt;/code&gt;. Everything after that – the hours, minutes, and seconds – is matched automatically because of the "match all" combination (.*). If you want to get today's date automatically in suitable format, you can use the common Linux &lt;code&gt;/bin/date&lt;/code&gt; command with this special formatting: &lt;code&gt;date +"%a %b %d"&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Continuing further with the regular expression, the two matches that will be referenced later are in brackets. The expression inside the brackets of the first one, &lt;code&gt;\[client ([0-9|\.]*)\]&lt;/code&gt;, is the simplest way to match the IP address of the remote client. The second bracketed expression, &lt;code&gt;\[id "([0-9]{6})"\]&lt;/code&gt;, matches the ID of the ModSecurity rule. All officially distributed ModSecurity rules are six digits. If you have rules with different numbering, make sure to adjust the expression.&lt;/p&gt;
&lt;p&gt;The entire regular expression will match every IP address and ModSecurity ID from the log. If you have a lot of traffic and many ModSecurity rules, you may end up flooded with information, so you should apply some filters.&lt;/p&gt;
&lt;p&gt;First, try to whitelist legitimate bots and disregard them. Most legitimate bots send valid requests and usually do not trigger ModSecurity alerts, but there are exceptions, such as some monitoring tools and less popular search engines. If you know of such an IP address – let's say for example 10.1.1.1 – you can whitelist it directly in ModSecurity's configuration file /etc/httpd/conf/crs/whitelists.conf with the directive &lt;code&gt;SecRule REMOTE_ADDR "^10.1.1.1" phase:1,nolog,allow,ctl:ruleEngine=off&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;However, often you deal with a large array of IP addresses and it's not feasible to whitelist them all. You should therefore find a way to check whether reported addresses are legitimate and avoid blocking them. One way to do that is to check whether the address has an authentic reverse DNS resolution. If it does, you can check whether its domain matches a list of domains you have whitelisted. You can see how this is implemented with a Perl subroutine called &lt;code&gt;legitimate_bot_check&lt;/code&gt; in the example script at the end of the article.&lt;/p&gt;
&lt;p&gt;To further reduce false-positive ModSecurity alerts, it is useful to establish some thresholds, and disregard IP addresses or ModSecurity IDs whose counters are below the threshold. This is necessary because even the most compliant client and regular visitor may trigger a complex ModSecurity rule, which makes it impractical to investigate every triggered rule. You can generally disregard IP addresses and rules with few hits. You can see just how to do this in the example script.&lt;/p&gt;
&lt;h3&gt;How to use the accumulated information&lt;/h3&gt;
&lt;p&gt;If you use this regular expression, your script will have a list of suspicious IP addresses and ModSecurity IDs and some counters for them. Here are a few ideas about how to make good use of this information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Examine an activity report – Receive regular email reports about the accumulated information to get an overall view of the attacks against your server. You'll see how in the example script.&lt;/li&gt;
&lt;li&gt;Block attackers – Once the counter for an IP address exceeds a threshold, you should block it. Aggressive attackers not only pose security risks but also consume system resources. You can block an address either manually or by programming it to happen automatically. Iptables is always a good choice for this purpose. A command such as &lt;code&gt;/sbin/iptables -I INPUT -s 10.0.0.1 -p TCP --dport 80,443 -j DROP&lt;/code&gt; denies access to ports 80 and 443 for the IP address 10.0.0.1.&lt;/li&gt;
&lt;li&gt;Improve ModSecurity rules – After evaluating the counters for each ModSecurity rule, you may find that some IDs are commonly blocking valid requests. Investigate every ID that has been triggered more than 100 times and make sure it's applicable for your environment. If one is not, disable it so it cannot block valid requests. You can do this with the ModSecurity directive &lt;code&gt;SecRuleRemoveById [ID1] [ID2] ...&lt;/code&gt; in the a file /etc/httpd/conf/crs/exceptions.conf.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;An example script&lt;/h3&gt;
&lt;p&gt;Here's an example script that implements all of the above features and sends an email message with a report. You should be able to use this script after tailoring it slightly to your environment. Set it to run as a cron job just before midnight so that it analyzes the information for a full day.&lt;/p&gt;
&lt;pre&gt;#!/usr/bin/perl

use warnings;
use strict;
use Socket;

# Define your admin email. This is where you will receive the reports
my $admin_mail = 'admin_reports@example.org';

# My from email. This is the email that mails will appear from

my $from_mail = 'sender@example.org';

# Define either the first argument as the Modsecurity Log or hardcode it (default)
# my $file = $ARGV['0'];
my $file = '/var/log/httpd/error_log';

# Create the hashes for the attackers and the ModSecurity ids.
# The keys for the attackers hashes are the remote client IPs. The values are the number of times this IP has appeared in the ModSecurity log with a triggered rule.
# The keys for the sec_ids hash are the IDs of the triggered ModSecurity ids. Their values are the number of times each of these rules has been triggered. 

my %attackers = ();
my %sec_ids = ();

# Get the current date in the format 'Fri Feb 17'. This is necessary for log files.
# You can also put a static date for a certain period of time

my $date = `date +"%a %b %d"`;
#my $date = 'Sun May 05'; #you can also specify a custom date here
# Remove the new line after the end of the date string
chomp($date);

# The search pattern for the ModSecurity rules from the Apache error log
my $search_pattern = '\['.$date . '.*\[client ([0-9|\.]*)\] ModSecurity.*\[id "([0-9]{6})"\]';

# From the log we're counting IPs and rules hit. To avoid showing all of them we're setting some thresholds. 
# $ips_threshold - the threshold of triggered ModSecurity rules above which IPs should be accounted for.
# $rules_threshold - the threshold of counting the IDs of triggered rules
# Increase these thresholds if you have a lot of rules and many legitimate non-complying clients

my $ips_threshold = 100;
my $rules_threshold = 100;

# Enable blocking or use only reporting. Specify 1 if you want any enabled.
my $blocking = 0;
my $reporting = 1;

# How ips should be blocked. Use iptables rule and the INPUT chain. In most cases just blocking the default web ports 80 and 443 is sufficient
sub block_command{
    my $ip = $_[0];
    system("/sbin/iptables -I INPUT -s ".$ip." -p TCP --dport 80,443 -j DROP");
}

# Create some safeguard against blocking legitimate IPs.
# For example, to avoid blocking legitimate bots, search engines and monitoring tools whitelist them here.
# In this subroutine whitelist search engines and make sure there is reverse resolving for them.

sub legitimate_bot_check {
    # Take the first argument of the routine as the remote IP. For example 66.249.66.1
    my $ip = $_[0];
    
    # Confirm there is a proper reverse DNS record or exit with false. For the IP 66.249.66.1 this should return crawl-66-249-66-1.googlebot.com.
    my $iaddr = inet_aton($ip) or return 0;
    
    # Confirm the previously obtained reverse DNS record (crawl-66-249-66-1.googlebot.com) points to the same IP (66.249.66.1) or exit with false
    my $name  = gethostbyaddr($iaddr, AF_INET) or return 0; 
    
    # Once you prove the IP has an authentic reverse DNS, check if it is among popular bots. 
    # If yes, exit with 'true' meaning that the IP shouldn't be counted
    if (gethostbyname($name) eq $iaddr) {
            if ($name =~ m/(yandex\.com$|search\.msn\.com$|googlebot\.com$|yahoo\.com$|baidu\.jp$|baidu\.com$|pingdom\.com$|monitorengine\.com$)/) {
                return 1;
            }
    } else {
        return 0; 
    }
}

# Open the log file for reading and prepare it for search
open LOGFILE, '&amp;lt;', $file or warn "Unable to open log file: $file!\n";

# Create an array from the contents of the file so that we can iterate through it
my @logarray = &amp;lt;LOGFILE&amp;gt;;

for (@logarray) {
    # Create a conditional if a row matches our search pattern
    if ($_ =~ /$search_pattern/) {
        # For each match increase the number of hits for each remote IP
        $attackers{$1}++;
        # For each match increase the number of hits for each unique ModSecurity ID
        $sec_ids{$2}++;
    }
}

# Close the log file safely
close LOGFILE;

# Iterate through the attackers hash
while ( my ($attacker_ip,$number_of_hits) = each %attackers ) {    
    # Apply the thresholds and filter the data
    # First filter the attackers.
    # Besides applying the threshold make sure you also apply some logic for whitelisting legitimate IPs such as the legitimate bots subroutine.    
    if ($number_of_hits &amp;lt; $ips_threshold or &amp;amp;legitimate_bot_check($attacker_ip)) {
        delete($attackers{$attacker_ip});
    }    
}

# Apply the threshold for the ModSecurity rules.

while ( my ($rule_id,$counter) = each %sec_ids ) {
    delete($sec_ids{$rule_id}) if $counter &amp;lt; $rules_threshold;    
}
        
# If blocking is enabled block the suspicious IPs.
if ($blocking) {
    while ( my ($attacker_ip,$number_of_hits) = each %attackers ) {
        &amp;amp;block_command($attacker_ip);
    }
}

# Send a report if enabled. Pipe the mail text to sendmail.

if ($reporting) {
    open(MAIL, "|/usr/sbin/sendmail -t");

    print MAIL "From: $from_mail\n";
    print MAIL "To: $admin_mail\n";
    print MAIL "Subject: Mod Security Stats\n\n";

    print MAIL "Attacking IPs and number of hits:\n";
        while ( my ($attacker_ip,$number_of_hits) = each %attackers ) {
            print MAIL "$attacker_ip =&amp;gt; $number_of_hits\n";
    }
    print MAIL "\nModsecurity IDs and their counters:\n";
        while ( my ($rule_id,$counter) = each %sec_ids ) {
            print MAIL "Rule ID $rule_id hit $counter number of times.\n";
    }
    close(MAIL);
}
&lt;/pre&gt;
&lt;p&gt;Once you're running the script daily, you will save time on manual jobs such as analyzing the logs and blocking intruders. By digging through the logs and implementing a few additional features, you can turn ModSecurity into a comprehensive intrusion detection and protection system. All it takes is some simple programming and certain logic.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/291730/Use-Perl-to-enhance-ModSecurity&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/gJcV_OlfzCc" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Thu, 23 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:291730</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/291730/Use-Perl-to-enhance-ModSecurity</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/290910/The-secret-to-great-reporting-with-Drupal-7#Comments</comments><slash:comments>0</slash:comments><title>The secret to great reporting with Drupal 7</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/hbUeC11blzc/The-secret-to-great-reporting-with-Drupal-7</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, the popular CMS platform, doesn't just allow you to create and manage content. You can also set up reporting options to find out more about how your site is being used and visited. Data on user access, content creation, user interaction, and other metrics can help you to modify your site to provide a better experience for users. Reports also support you in assessing how well you're meeting your goals for the site. Let's set up some basic reporting in Drupal 7, and see how to use the View and Google Analytics modules to get more report data.&lt;/p&gt;
&lt;p&gt;The core Drupal 7 install has a Reports tab, but it has fairly limited functionality. The handful of things it does cover includes update reports and log messages. More usefully, it also summarizes the "access denied" and "page not found" errors your site reports, which can alert you to potential problems, as well as the top search phrases used, which can help you tweak site content to better suit your users.&lt;/p&gt;
&lt;p&gt;If you want to get more site information, a couple of report modules are available, but unfortunately neither is a great fit. &lt;a href="http://drupal.org/project/report"&gt;Report&lt;/a&gt;, which tracks user data and content activity, is not available (yet?) for Drupal 7; and &lt;a href="http://drupal.org/project/report_builder"&gt;Report Builder&lt;/a&gt; is unsupported and no longer under active development, so it's not a great choice for a production site.&lt;/p&gt;
&lt;h3&gt;Google Analytics and traffic tracking&lt;/h3&gt;
&lt;p&gt;Luckily, the &lt;a href="http://drupal.org/project/google_analytics_reports"&gt;Google Analytics Reports&lt;/a&gt; module for Drupal 7 provides graphical reporting of tracking data. After it connects your site to a Google account that is set up with Google Analytics, it can show you where your visitors are clicking through from and which pages and links they're visiting. It's easy to set up, but you must do a few things before you can get it running.&lt;/p&gt;
&lt;p&gt;You'll need to install the PHP &lt;a href="http://olex.openlogic.com/packages/curl"&gt;cURL&lt;/a&gt; library on your server (&lt;code&gt;sudo apt-get install php5-curl libcurl4 libcurl4-dev&lt;/code&gt; on Ubuntu or Debian, or &lt;code&gt;sudo yum install curl curl-devel&lt;/code&gt; on Red Hat and &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt;). You must also install a few Drupal modules from the Drush command shell:&lt;/p&gt;
&lt;pre&gt;drush dl google_analytics_reports 
drush dl chart 
drush dl oauth
&lt;/pre&gt;
&lt;p&gt;Once that's done, go to the Modules admin page on your site and enable Google API, OAuth, and Charts. Reload the page, then click Settings next to the Google API module to configure it. You'll need to connect the module with a Google account that has Google Analytics already set up, and authorize it. Once that's all set up you can go to Reports -&amp;gt; Google Analytics Summary to get a report of site traffic.&lt;/p&gt;
&lt;p&gt;As a bonus, the Charts API you've set up also gives you a Charts view of various aspects of site activity, and is also available from the Reports tab.&lt;/p&gt;
&lt;h3&gt;Custom reports with Views&lt;/h3&gt;
&lt;p&gt;If you want to set up your own custom reports, the easiest way to do this for most sites is to use the &lt;a href="http://drupal.org/project/views"&gt;Views&lt;/a&gt; module. Install it (and the &lt;a href="http://drupal.org/project/advanced_help"&gt;Advanced Help&lt;/a&gt; module, to access detailed Views help via the Drupal admin console) with &lt;code&gt;drush&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;drush dl views 
drush dl advanced_help
&lt;/pre&gt;
&lt;p&gt;Enable the Views module in the Modules tab, then go to Structure -&amp;gt; Views to set up your views. You might want to set up a few default Views (such as Archive, Backlinks, and Recent Comments) for your site, but the only one that's of interest to us for report purposes is Tracker. Enable it, then click Edit to see what the view looks like. Note that while by default it is viewable by anyone, if you click on Access you can apply permission/role access to limit its use to only administrators, for example.&lt;/p&gt;
&lt;p&gt;Almost certainly, though, what you want is a custom view, to report on exactly the information you're interested in. Effectively, a view is an SQL query that pulls information from the Drupal back end database. You can query by field (the SQL &lt;code&gt;SELECT&lt;/code&gt; query) and relationships (&lt;code&gt;INNER JOIN&lt;/code&gt;), filter the data (&lt;code&gt;WHERE&lt;/code&gt;), and sort it (&lt;code&gt;ORDER BY&lt;/code&gt;). You can also choose how it's displayed and to whom.&lt;/p&gt;
&lt;p&gt;Let's try a basic example. We'll look at which tags are on the most posts, and which get the most comments, which may indicate what sort of content is most popular on your site (and whether the popular content is the sort of content that you're actually producing most of!):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Click "new view" and give the new view a name, such as "Tag Report."&lt;/li&gt;
&lt;li&gt;In the Show box, select "Taxonomy terms," and type "Tags." Choose "Table" for display format, then click the Continue button.&lt;/li&gt;
&lt;li&gt;You'll now see the detailed setup of the View. Click the Advanced dropdown, over on the right, to reveal the Relationships option, and add a relationship: "Taxonomy term: Content using Tags."&lt;/li&gt;
&lt;li&gt;Under Other, click Aggregate.&lt;/li&gt;
&lt;li&gt;Now go back to Fields, on the left side. This is where you choose the fields to show in your display table. Add three fields:&lt;ol&gt;
&lt;li&gt;Taxonomy term: Name; set aggregation to "Group results together."&lt;/li&gt;
&lt;li&gt;Content: Nid; set aggregation to "Count."&lt;/li&gt;
&lt;li&gt;Content: Comment count; set aggregation to "Sum."&lt;/li&gt;
&lt;/ol&gt;&lt;/li&gt;
&lt;li&gt;The default filter is to show only posts that are published. You can change this if you want to, but here it's unlikely to be helpful, as unpublished posts won't have comments.&lt;/li&gt;
&lt;li&gt;Finally, you can choose to sort either on comment count or on node (page/article) count.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At the bottom of the page you'll see a preview of what the View will look like, and it is updated whenever you make a change. If you're happy with what you see, you can save it, and consider other relevant settings, such as whether to restrict access to administrators only. Reload the View page and you can see which of your tags are the most popular. (Note, however, that this setup won't show pages that have no tags at all, so be aware of that when you consider the data.)&lt;/p&gt;
&lt;p&gt;This is only a basic example of how to work with Views and generate site information and reports. You can also change the way information is shown to you, and chop and slice it in various ways that fit your needs. You can do a bunch of other things with Views, especially when using Relationships. For more on the details of Relationships and how they work, see the Relationships page on the Views Advanced Help; basically, if you include a relationship to the base query into your View, more information pertaining to that relationship becomes available. In this way you can access other tables in addition to the base one of your query; hence the similarity with &lt;code&gt;JOIN&lt;/code&gt; in SQL.&lt;/p&gt;
&lt;p&gt;If the default Views options don't cut it for you, you can use the Views API to generate plugins and handlers. It's a very flexible system that's well worth taking the time to get to know.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/290910/The-secret-to-great-reporting-with-Drupal-7&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/hbUeC11blzc" height="1" width="1"/&gt;</description><dc:creator>Juliet Kemp</dc:creator><pubDate>Mon, 20 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:290910</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/290910/The-secret-to-great-reporting-with-Drupal-7</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/289690/A-more-colorful-LibreOffice-unveiled#Comments</comments><slash:comments>2</slash:comments><title>A more colorful LibreOffice unveiled</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/ceCtHjPj6To/A-more-colorful-LibreOffice-unveiled</link><description>&lt;p&gt;In &lt;a href="http://www.openlogic.com/wazi/bid/289688/Toward-a-more-colorful-LibreOffice"&gt;the first article in this series&lt;/a&gt; I pointed out some problems I and other LibreOffice users have with the standard LibreOffice color palette, and I talked about how colors are specified, both on computers in general and within LibreOffice .soc files. Let's now see how to generate a new set of colors.&lt;/p&gt;
&lt;p&gt;The process requires finding some base colors to start with and scripting some code to build darker and lighter variations of them. Since I'm not particularly gifted (rather the contrary!) in artistic color-related work, I needed to get my colors from someplace. The World Wide Web Consortium (W3C) provides a list of &lt;a href="http://www.w3.org/TR/css3-color/#svg-color"&gt;color names as used in CSS&lt;/a&gt; (cascading style sheets). However, that list is in alphabetic order, and I'd rather group colors in families (reds, greens, blues, browns, and so on). A &lt;a href="http://en.wikipedia.org/wiki/Web_colors#X11_color_names"&gt;Wikipedia article&lt;/a&gt; provides a suitable table. With some cutting, pasting, and minor editing, I ended with the following text file:&lt;/p&gt;
&lt;pre&gt;REDS
IndianRed CD 5C 5C 205 92 92
LightCoral F0 80 80 240 128 128
Salmon FA 80 72 250 128 114
DarkSalmon E9 96 7A 233 150 122
LightSalmon FF A0 7A 255 160 122
Red FF 00 00 255 0 0
Crimson DC 14 3C 220 20 60
FireBrick B2 22 22 178 34 34
DarkRed 8B 00 00 139 0 0

PINKS
Pink FF C0 CB 255 192 203
LightPink FF B6 C1 255 182 193
HotPink FF 69 B4 255 105 180

&lt;em&gt;...many lines snipped out...&lt;/em&gt;

DimGray 69 69 69 105 105 105
LightSlateGray 77 88 99 119 136 153
SlateGray 70 80 90 112 128 144
DarkSlateGray 2F 4F 4F 47 79 79
Black 00 00 00 0 0 0
&lt;/pre&gt;
&lt;p&gt;I left blank lines for clarity; our script will ignore them. Lines with a single name identify color families, whose names I took from the web page. (You'll see why I kept those lines in a little bit.) Other lines have seven fields: a color name, the three hexadecimal RGB values, and their three decimal equivalents; we won't be using the hex values, but leaving them was simpler than removing them! We'll use this basic color table as a basis for our color variations, after we tweak it a bit.&lt;/p&gt;
&lt;p&gt;The W3C also defines the &lt;a href="http://www.w3.org/TR/REC-html40/types.html#h-6.5"&gt;16 basic colors&lt;/a&gt; supported with by Windows VGA palette. I added them to the top of the colors table. Finding the decimal equivalents is easy, since the only hex numbers that appear are 00, 80, C0, and FF, which are 0, 128, 192, and 255 in base 10. I call this family "BASIC," and I opted to give its colors all-uppercase names. These colors are duplicated elsewhere in the X11 colors table, but being able to find, say, red, at two different places is no big deal.&lt;/p&gt;
&lt;pre&gt;BASIC
WHITE FF FF FF 255 255 255
SILVER C0 C0 C0 192 192 192
GRAY 80 80 80 128 128 128
BLACK 00 00 00 0 0 0
RED FF 00 00 255 0 0
MAROON 80 00 00 128 0 0
YELLOW FF FF 00 255 255 0
OLIVE 80 80 00 128 128 0
LIME 00 FF 00 0 255 0
GREEN 00 80 00 0 128 0
AQUA 00 FF FF 0 255 255
TEAL 00 80 80 0 128 128
BLUE 00 00 FF 0 0 255
NAVY 00 00 80 0 0 128
FUCHSIA FF 00 FF 255 0 255
PURPLE 80 00 80 128 0 128
&lt;/pre&gt;
&lt;p&gt;Finally, after some experimenting, I noted that a couple of nice LibreOffice colors, Pale Yellow and Pale Green (actually, more like Pale Cyan) were missing. Looking at the standard LibreOffice colors list I found that Pale Yellow was (255, 255, 204), and Pale Green was (204, 255, 255). Noticing the pattern, I also tried out the (255, 204, 255) combination, and got a Pale Rose. Since I like these three colors, I added them in the Yellow, Pinks, and Blues families; 204 is CC in hexadecimal, if you are curious.&lt;/p&gt;
&lt;pre&gt;PaleYellow FF FF CC 255 255 204
PalePink FF CC FF 255 204 255
PaleCyan CC FF FF 204 255 255
&lt;/pre&gt;
&lt;p&gt;The full list is in the downloadable file &lt;a href="https://github.com/fkereki/LibreOffice-Colors/blob/master/colors.x11"&gt;colors.x11&lt;/a&gt;. At this point, we have a satisfactory table with all the basic X11 colors plus some additions, from which we can derive as many variations as we please. Time for some scripting!&lt;/p&gt;
&lt;h3&gt;Getting color variants&lt;/h3&gt;
&lt;p&gt;Let's say we want to produce some variations of color (240,64,128), a sort of dark pink. We want to get both lighter and darker versions of it, so we have to modify its R, G and B values appropriately.&lt;/p&gt;
&lt;p&gt;Suppose we want to create four darker variations, ending up in black. Given that the R component must go from 0 (darkest) to 240 (the original color) in four steps, the three intermediate colors we'll need will have R values of 60, 120 and 180; the G component will be 16, 32, and 48, and the B component 32, 64, and 96. Thus, the three colors we'll produce are (60, 16, 32), (120, 32, 64), and (180, 48, 96). Similarly, the three lighter colors will be (244, 112, 160), (248, 160, 192), and (252, 208, 224).&lt;/p&gt;
&lt;p&gt;&lt;img id="img-1367888281240" src="http://www.openlogic.com/Portals/172122/images/figure.6b.color.graph.png" border="0" alt="Each color component (R, G, B) varies in linear fashion to the  extremes, black and white" width="300" height="282" style="height: 282px; width: 300px;"&gt;&amp;nbsp;&amp;nbsp;&lt;img src="http://www.openlogic.com/Portals/172122/images/figure.6.color.variations.png" border="0" alt="Each darker or lighter variation corresponds to a proportional decrease  or increase in its R, G, and B components"&gt;&lt;/p&gt;
&lt;p&gt;Of course, you could have any number of variations other than four, and you need not have the same number of darker and lighter versions. Also note that not all variations are really interesting; as you go to the extremes, they become either too dark or too light, so you'll probably want to pick just a few of all the available colors, most likely centered around the original one.&lt;/p&gt;
&lt;p&gt;Now that we know how to produce variations from a given color, we can script the process with &lt;a href="http://www.grymoire.com/Unix/Awk.html"&gt;awk&lt;/a&gt;. Awk is an interpreted programming language, standard in Unix and Linux environments, often used for processing text files. Its name comes from the last names of its creators: Aho, Weinberger, and Kernighan. An awk program consists in a series of conditions and actions. Each input line is tested, and if a condition is satisfied, awk executes the corresponding actions, programmed in a C-like language. Conditions usually involve pattern-matching to regular expressions, which makes awk suitable for text file processing. Two special conditions, BEGIN and END, are respectively satisfied at the beginning of the program run and when no more input is available. You can execute short awk programs – one-liners – directly from the command line for simple transformations.&lt;/p&gt;
&lt;h3&gt;Producing the actual tables&lt;/h3&gt;
&lt;p&gt;Since the transformations needed to build a color palette from the color list aren't that hard, the full program turns out to be just a few lines long. Given the .soc format that we saw in the last article, what we basically require is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;At the beginning, output two header lines, the ones beginning with "&amp;lt;?xml..." and "&amp;lt;ooo:color-table..."&lt;/li&gt;
&lt;li&gt;For each color in our list, output several "&amp;lt;draw:color" lines&lt;/li&gt;
&lt;li&gt;Output a closing "&amp;lt;/ooo:color-table&amp;gt;" footer line&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How many variations of each color should we produce? LibreOffice shows colors eight in a row, so producing a multiple of eight colors would look good. Using another number would cause LibreOffice to split the variations over different lines – not so clear. I started by splitting the range from the extremes (black and white) to each color in six steps. After examining the resulting colors, I decided to keep four lighter variations, the original color, and three darker variations; other variations end up looking too similar to white or black. Here's the first part of the colors.awk script; you can &lt;a href="https://github.com/fkereki/LibreOffice-Colors/blob/master/colors.awk"&gt;download the complete script&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;BEGIN {
  # We'll create 8 variations of each color; 4
  # lighter ones, plus the original color, plus 3
  # darker ones. We'll split the range between the
  # color and black or white in 6 steps, so there
  # will be a margin between the extremes and our
  # variations.
  VARIATIONS = 8
  INITIAL = 4
  STEPS = 6

  # The following constants come in handy
  # to shorten printf lines for publication
  DC = "draw:color"
  DN = "draw:name"
  UR = "urn:oasis:names:tc:opendocument:"
  XM = "xmlns:"

  # Print the header for the color table
  printf "&amp;lt;?xml version='1.0' " \
    "encoding='UTF-8'?&amp;gt;\n" \
    "&amp;lt;ooo:color-table\n" \
    XM "office='" UR XM "office:1.0' \n" \
    XM "draw='" UR XM "drawing:1.0'\n" \
    XM "xlink='http://www.w3.org/1999/xlink'\n" \
    XM "svg='http://www.w3.org/2000/svg'\n" \
    XM "ooo='http://openoffice.org/2004/office'&amp;gt;\n"
}
&lt;/pre&gt;
&lt;p&gt;Generating color variations is simple math, but how shall we name the colors we produce? I incorporated the family name of each color to produce names such as REDS/LightCoral, PINKS/HotPink, and PURPLES/Thistle, because then by just typing the first letters of a family color, LibreOffice immediately moves to the colors in that family. To distinguish colors, I added "+1," "+2," etc., to the lighter variations, and "-1," "-2," etc., to the darker ones. I also decided not to make variations of the basic VGA colors, given that they are duplicated elsewhere in the color list.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/figure.7.pick.color-resized-600.png" border="0" alt="Finding colors is easier if each color name is preceded by the family  name"&gt;&lt;/p&gt;
&lt;p&gt;The main loop of the awk script matches:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;empty lines, which are just ignored&lt;/li&gt;
&lt;li&gt;lines with a single field (family names), which are saved for later&lt;/li&gt;
&lt;li&gt;lines in the BASIC family, which produce just a single color, no variations at all&lt;/li&gt;
&lt;li&gt;lines in other families, which produce a number of variations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the code, $1, $2, etc., refer to the fields in the line, so $1 is a color name, and $5 to $7 its RGB components. We need a &lt;code&gt;round()&lt;/code&gt; function of our own, because awk doesn't provide one. Here's the body of the script:&lt;/p&gt;
&lt;pre&gt;NF==1 {
  colorPrefix = $1
}

NF==7 &amp;amp;&amp;amp; colorPrefix=="BASIC" {
  printf "&amp;lt;" DC " " DN "='BASIC/%s' " \
    DC "='#%02x%02x%02x'/&amp;gt;\n", \
    $1, $5, $6, $7
}

NF==7 &amp;amp;&amp;amp; colorPrefix!="BASIC" {
  for (i=INITIAL; i&amp;gt;INITIAL-VARIATIONS; i--) {
    if (i&amp;lt;0) {
      red = $5 + round(i * $5 / STEPS)
      green = $6 + round(i * $6 / STEPS)
      blue = $7 + round(i * $7 / STEPS)
    } else {
      red = $5 + round(i * (255-$5) / STEPS)
      green = $6 + round(i * (255-$6) / STEPS)
      blue = $7 + round(i * (255-$7) / STEPS)
    }

    if (i==0) {
      printf "&amp;lt;" DC " " DN "='%s/%s' " \
        DC "='#%02x%02x%02x'/&amp;gt;\n", \
        colorPrefix, $1, red, green, blue
    } else {
      printf "&amp;lt;" DC " " DN "='%s/%s%+i' " \
        DC "='#%02x%02x%02x'/&amp;gt;\n", \
        colorPrefix, $1, i, red, green, blue
    }
  }
}

function round(r) {
  return int(0.5 + r);
}
&lt;/pre&gt;
&lt;p&gt;We print hex digits with the &lt;code&gt;'#%02x%02x%02x'&lt;/code&gt; format string. After this code, we just have to output the required XML footer for the color list:&lt;/p&gt;
&lt;pre&gt;END {
  # Print the footer for the color table
  print "&amp;lt;/ooo:color-table&amp;gt;\n"
}
&lt;/pre&gt;
&lt;p&gt;Running this script is simple: &lt;code&gt;awk -f colors.awk &amp;lt;colors.x11 &amp;gt;&lt;em&gt;pick.a.name&lt;/em&gt;.soc&lt;/code&gt;. I called my file &lt;a href="https://github.com/fkereki/LibreOffice-Colors/blob/master/colors.soc"&gt;colors.soc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Copy the newly produced file to your LibreOffice directory and rename it standard.soc so LibreOffice will use it by default, after first renaming the original standard.soc file to original.soc, just in case you want to go back to it.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/figure.8.new.color.table-resized-600.png" border="0" alt="The result of our work - a nice table with plenty of nicely graded color  variations"&gt;&lt;/p&gt;
&lt;!-- figure.8.new.color.table.png goes here
Caption: The result of our work; a nice table with plenty of nicely graded color 
variations. --&gt;
&lt;p&gt;After you look at your new color table, you might consider going down to four colors if eight are too many. For less stark color graduations, increase the number of steps; fewer steps produce higher contrasts. You might pare down the GRAYS and WHITES families. Finally, you might want to include the "Chart" colors LibreOffice uses, with no variations (as with the BASIC color family) and no renaming.&lt;/p&gt;
&lt;h3&gt;In conclusion&lt;/h3&gt;
&lt;p&gt;Open standards mean that you'll rarely be stuck with a problem if you are willing to do some work. In this instance, we were able to extend LibreOffice with a full color library, to allow us to work with presentations, spreadsheets, and other documents using a more attractive palette.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/289690/A-more-colorful-LibreOffice-unveiled&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/ceCtHjPj6To" height="1" width="1"/&gt;</description><dc:creator>Federico Kereki</dc:creator><pubDate>Thu, 16 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:289690</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/289690/A-more-colorful-LibreOffice-unveiled</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/289688/Toward-a-more-colorful-LibreOffice#Comments</comments><slash:comments>3</slash:comments><title>Toward a more colorful LibreOffice</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/LHhMrkSG9sk/Toward-a-more-colorful-LibreOffice</link><description>&lt;p&gt;Recently, I was working on an Impress presentation, and I needed more colors than &lt;a href="http://olex.openlogic.com/packages/libreoffice"&gt;LibreOffice&lt;/a&gt; provides with its standard color picker. Specifically, I needed several light colors, but the standard color list includes only a few light blue possibilities. I could have defined my own colors manually using the Color Picker, but "mixing" colors by specifying &lt;a href="http://www.w3schools.com/html/html_colors.asp"&gt;RGB&lt;/a&gt; or &lt;a href="http://graphicdesign.about.com/od/colorbasics/a/cmyk.htm"&gt;CMYK&lt;/a&gt; numbers is a cumbersome, hit-or-miss process. LibreOffice also lets users load predefined color libraries, but none of the ones I found suited me. Instead, by working with web-standard colors plus a little bit of &lt;a href="http://www.gnu.org/software/gawk/manual/gawk.html"&gt;awk&lt;/a&gt; scripting, I managed to create my own color list, providing well-organized colors, grouped in families, with as many color variations as I wanted.&lt;/p&gt;
&lt;p&gt;The Impress and Draw components let you load a new color list and add colors to it, which is an option if you just need one or two new colors and know how to define them. (An aside: Any color changes you make in Impress or Draw become available for all LibreOffice components.) Open Impress or Draw, go to Format -&amp;gt; Area -&amp;gt; Colors, and you'll see the table of all available colors, with their RGB and CMYK equivalents, along with commands for editing the list:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/figure.1.format.area.colors-resized-600.png" border="0" alt="The standard LibreOffice color list"&gt;&lt;/p&gt;
&lt;p&gt;Modifying the standard color table is straightforward. To add a new color, enter a name for it, select its R, G, and B values, and click the Add button. Your new color is added at the bottom of the table. To modify an existing color, click on it, change its R, G, and B values, and click on Modify. You can select a color several different ways by clicking on the Edit button (see figure below). Finally, to delete a color from the color table, select it and click on Delete.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/figure.2.color.edit-resized-600.png" border="0" alt="LibreOffice lets you handpick a color in several different ways"&gt;&lt;/p&gt;
&lt;!-- figure.2.color.edit.png goes here
Caption: LibreOffice lets you handpick a color in several different ways. --&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;LibreOffice or OpenOffice?&lt;/strong&gt;&lt;br&gt;LibreOffice was forked off OpenOffice in 2010, but the color lists you develop apply equally well to both, though you might need to make some adjustments to file names and locations.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you were skilled enough, you could create a whole set of colors in the standard table by using these tools. LibreOffice saves its standard color table in the file standard.soc, whose location varies from distribution to distribution; openSUSE saves it in $HOME/.config/libreoffice/4-suse/user/config, but &lt;a href="https://wiki.documentfoundation.org/UserProfile"&gt;the standard place&lt;/a&gt; is $HOME/.libreoffice/4/user/config. You can learn the location by clicking on the Load Color List icon in the Format -&amp;gt; Colors dialog and taking note of the directory it shows.&lt;/p&gt;
&lt;p&gt;(By the way, different distributions not only change the location of the file, but also its contents. For instance, Ubuntu includes three special colors – Ubuntu Orange, Ubuntu Yellow, and Ubuntu Red – and Red Hat includes Red Hat 1 through Red Hat 5.)&lt;/p&gt;
&lt;p&gt;LibreOffice also provides alternate color lists, with different sets of colors. Click on the Load Color List icon in the Format -&amp;gt; Colors dialog to see a list of available *.soc files. (I assume, but couldn't verify, that "soc" stands for "set of colors.")&lt;/p&gt;
&lt;p&gt;I tried out many tables, but despite getting more options than with the standard table, I still wasn't satisfied. I finally decided to produce my own color list, with enough variations to suit me, grouped in color families, so finding the right shade would be easier. I'll walk you through the process, but first you need to know a little about how computers represent colors.&lt;/p&gt;
&lt;h3&gt;Color models: RGB and CMYK&lt;/h3&gt;
&lt;p&gt;Since computers are digital machines, colors must be represented as numbers, and a color model is a way of doing just that. RGB is an additive model, based on red, green, and blue lights, which added together in varying intensities produce colors. Colors in the RGB model are specified by three numbers, from 0 (minimum) to 255 (maximum). Zero intensity for all lights produces no color at all (black) while maximum intensity for all colors gives white. If intensities are not all the same, you get variously colored hues. Higher component values mean lighter colors (all the way from black to white) so to get a lighter version of a RGB color, you have to increase its R, G, and B values, and for a darker version, you decrease those values.&lt;/p&gt;
&lt;p&gt;Computers use RGB for screens, but for printed output CMYK is standard. CMYK is a subtractive color model based on four ink colors: cyan, magenta, yellow, and key (black). Using no inks at all is plain white. Each ink absorbs certain frequencies of light, so mixing inks in specific proportions can produce other colors. Mixing cyan, magenta, and yellow inks in maximum proportions (100%) should produce black, but actually gets you a dark muddy brown, and that's why CMYK uses a fourth ink, black. CMYK colors are given by four percentages, so a green color could be produced by something around (15%, 0%, 35%, 35%) meaning 15% intensity of cyan, no magenta at all, and 35% intensities of both yellow and black.&lt;/p&gt;
&lt;p&gt;To produce darker and lighter variations, CMYK works the opposite way from RGB: Higher values (more ink) mean darker colors, and to get a lighter variation of a color (less ink) you have to lower its C, M, Y, and K values.&lt;/p&gt;
&lt;p&gt;By default, LibreOffice uses RGB to specify screen colors, and we'll use it when we create our color table. In binary, each color is represented by a 24-bit number, so there are 2^24 possible variations, or 16,777,216 colors in all.&lt;/p&gt;
&lt;h3&gt;What's a .soc like?&lt;/h3&gt;
&lt;p&gt;So much for the way colors are represented. The next step is to determine the format for .soc files. While downloading the full source code for the LibreOffice suite and searching around for the correct description was one way to figure that out, I felt that the file format shouldn't be too hard to deduce, and when I looked at a few .soc files on my own, that proved to be the case.&lt;/p&gt;
&lt;p&gt;Color lists are XML files that contain a &amp;lt;draw:color&amp;gt; element for each defined color, given by its RGB value in hexadecimal:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;ooo:color-table xmlns:office=
"urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:draw=
"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:ooo="http://openoffice.org/2004/office"&amp;gt;

&amp;lt;draw:color
    draw:name="Black" draw:color="#000000"/&amp;gt;
&amp;lt;draw:color
    draw:name="White" draw:color="#ffffff"/&amp;gt;
&amp;lt;draw:color
    draw:name="Blue" draw:color="#000080"/&amp;gt;
&amp;lt;draw:color
    draw:name="Green" draw:color="#008000"/&amp;gt;

&lt;em&gt;...many lines snipped out...&lt;/em&gt;

&amp;lt;draw:color
    draw:name="Chart 10" draw:color="#ff950e"/&amp;gt;
&amp;lt;draw:color
    draw:name="Chart 11" draw:color="#c5000b"/&amp;gt;
&amp;lt;draw:color
    draw:name="Chart 12" draw:color="#0084d1"/&amp;gt;
&amp;lt;/ooo:color-table&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Since XML files are text files, producing a table of such elements should be easy for a script – you just need to decide how to automatically generate variations for a table of colors and then write some awk code to do the actual work.&lt;/p&gt;
&lt;p&gt;So how are we to produce color variations? Given a base color, we can produce darker or lighter variations of it by modifying its R, G, and B values, but not haphazardly. If we make a large variation in the R component it should be accompanied by proportionally large variations in the G and B components, or we'll end up with a totally different hue.&lt;/p&gt;
&lt;p&gt;Of course, in order to accomplish this, we need a list of starting colors, which we can modify to get variations, and then do some calculations to actually produce the .soc file. To see how, &lt;a href="http://www.openlogic.com/wazi/bid/289690/a-more-colorful-libreoffice-unveiled" title="read part two of this series" target="_self"&gt;read part two of this series&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/289688/Toward-a-more-colorful-LibreOffice&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/LHhMrkSG9sk" height="1" width="1"/&gt;</description><dc:creator>Federico Kereki</dc:creator><pubDate>Mon, 13 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:289688</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/289688/Toward-a-more-colorful-LibreOffice</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/289652/Flexible-administration-with-Puppet-s-Facter-and-templates#Comments</comments><slash:comments>0</slash:comments><title>Flexible administration with Puppet's Facter and templates</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/mBu1SA3OeXA/Flexible-administration-with-Puppet-s-Facter-and-templates</link><description>&lt;p&gt;One of the strengths of &lt;a href="http://olex.openlogic.com/packages/puppet"&gt;Puppet&lt;/a&gt;, the IT automation application, is the flexibility it offers administrators to manage multiple servers through the use of customized templates and remote system facts, which are essentially variable values from remotely managed nodes. Thanks to this flexibility you can administer each Puppet node with instructions tailored for its specific environment – something you cannot do with simpler multiserver administration tools.&lt;/p&gt;
&lt;p&gt;As I talk about how to administer nodes with Puppet, I'll assume you are already acquainted with the software and have a working Puppet environment configured. If not, read &lt;a href="http://www.openlogic.com/wazi/bid/254233/Multiserver-administration-with-Puppet"&gt;Multiserver administration with Puppet&lt;/a&gt; to get started.&lt;/p&gt;
&lt;h3&gt;How to find out information about nodes&lt;/h3&gt;
&lt;p&gt;The better you know a Puppet node, the more optimally you can administer it. For example, when you define the global Apache configuration, it makes a big difference which nodes run which different operating systems and which have what number of CPUs and RAM capacity, so you can adapt the values for Apache's daemon options to match each node's system resources.&lt;/p&gt;
&lt;p&gt;You can get that kind of information with &lt;a href="http://puppetlabs.com/puppet/related-projects/facter/"&gt;Facter&lt;/a&gt;, a Puppet library and a command-line tool (/usr/bin/facter). Facter works with hashes of key and value pairs such as &lt;code&gt;memorytotal =&amp;gt; 4 GB&lt;/code&gt;, which is the hash for the total RAM. By default, it gives you more than 50 facts, from the type of the operating system and its architecture to the size of the RAM.&lt;/p&gt;
&lt;p&gt;To see all the available facts for a node, run the command &lt;code&gt;/usr/bin/facter&lt;/code&gt; without parameters. The number of values may vary depending on nodes' software and hardware specifications. For example, if a node has more than one NIC, Facter will report a fact hash for each NIC.&lt;/p&gt;
&lt;p&gt;If you want to get the value for a specific fact, specify this fact as the first argument of the command. For example, to find out if the node is a virtual or a bare-metal server, run &lt;code&gt;/usr/bin/facter is_virtual&lt;/code&gt;. This capability can be handy even outside of Puppet. Since Puppet and Facter run under multiple Linux and BSD flavors, you can use Facter instead of different OS-specific commands to find out information you need.&lt;/p&gt;
&lt;p&gt;Furthermore, Facter is extendable – you can teach it to work with your own facts. One way to do this is by exporting a Bash variable with a command such as &lt;code&gt;export FACTER_custom_fact=`cat /etc/redhat-release`&lt;/code&gt;. In this example, custom_fact is the name of the variable and it is the result of the execution of the shell command &lt;code&gt;cat /etc/redhat-release&lt;/code&gt;, which contains the Red Hat release information for the current version of CentOS. Once you've defined a custom fact, Facter works with it just as it does with any other fact. For more options and information, check Puppet's documentation about &lt;a href="http://docs.puppetlabs.com/guides/custom_facts.html"&gt;custom facts&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;How to use templates&lt;/h3&gt;
&lt;p&gt;You can combine Puppet facts with another useful Puppet feature – templates. Puppet templates are based on the &lt;a href="http://ruby-doc.org/stdlib-1.8.7/libdoc/erb/rdoc/ERB.html"&gt;Ruby templating system&lt;/a&gt; (ERB) and can be used in Puppet manifests (configuration files). Templates allow Puppet to use variables inside static text files, which makes them suitable for global configuration files that are adapted locally for a node's specific environment.&lt;/p&gt;
&lt;p&gt;By convention, you should place your Puppet templates in the subdirectory "templates" inside the directory of the module to which the template belongs. For example, for the NTP module, with which you manage the ntp service on the nodes, the path is /etc/puppet/modules/ntp. In this case you should place the templates in the directory /etc/puppet/modules/ntp/templates. Thus, when you refer to this template, you need only two pieces of information: the name of the module and the file of the template separated by a slash, such as test/example.erb.&lt;/p&gt;
&lt;p&gt;You can instruct Puppet to use a template by using the &lt;code&gt;template&lt;/code&gt; function. For example, you can generate one of the files (/etc/example.conf) for a module called "test" from a template by using the following code inside any Puppet manifest file:&lt;/p&gt;
&lt;pre&gt;file {'/etc/example.conf':
      content =&amp;gt; template('test/example.conf.erb'),
     }
&lt;/pre&gt;
&lt;p&gt;Templates are interpreted on each node during catalog compilation, when the node receives the Puppet master's instructions and prepares them for local execution. At that time Puppet substitutes all template variables with their corresponding local values, and the template example.conf.erb becomes the static file /etc/example.conf.&lt;/p&gt;
&lt;h3&gt;How to write templates&lt;/h3&gt;
&lt;p&gt;Template files are regular static text files with pieces of ERB code inside them. Don't worry if you are not acquainted with ERB because the basics are simple. In fact it is important to understand just two main concepts in order to start writing templates.&lt;/p&gt;
&lt;p&gt;The first concept is how to reference variables and Facter facts. Just like any other ERB variable inside the current scope, facts are referenced by placing the at-sign (@) in front of their names. ERB variables are referenced in such a way only inside templates, and you should not confuse them with the standard variables referenced by the dollar sign ($). Understanding this basic concept is enough to get you started. You can read more about &lt;a href="http://docs.puppetlabs.com/puppet/2.7/reference/lang_scope.html"&gt;the language scope&lt;/a&gt; if you want to get an idea about variable scoping and isolation.&lt;/p&gt;
&lt;p&gt;The second essential concept is how to specify ERB code inside templates with static text content. Denote the start and end of the ERB code with two different tags. The first tag is &lt;code&gt;&amp;lt;%= &lt;em&gt;code&lt;/em&gt; %&amp;gt;&lt;/code&gt;. The code inside this tag will be evaluated and the code block will be substituted with the result. This is useful for assigning configuration parameters from variables. For example, with this tag you can assign the ServerName parameter in Apache's configuration using the fully qualified domain name of the node as provided by Facter with the code &lt;code&gt;ServerName &amp;lt;%= @fqdn %&amp;gt;&lt;/code&gt;. When the template is processed and the code is evaluated you will end up with something like &lt;code&gt;ServerName somenode.example.org&lt;/code&gt; in the node's Apache configuration.&lt;/p&gt;
&lt;p&gt;The second tag for denoting start and end of ERB code is &lt;code&gt;&amp;lt;% &lt;em&gt;code&lt;/em&gt; %&amp;gt;&lt;/code&gt;. Unlike the first tag, this code does not provide output by default but rather is used for executing Ruby code. Having this powerful option gives you an abundance of options limited only by your programming skills. Most frequently you can use it to evaluate conditionals or go through iterations. For example, try a conditional where you want a specific configuration option to be placed only for virtual servers:&lt;/p&gt;
&lt;pre&gt;&amp;lt;% if @is_virtual == "true" -%&amp;gt;
Here goes the specific configuration option
&amp;lt;% end -%&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Notice that since this is a multiline statement, instead of its regular closing tag &lt;code&gt;%&amp;gt;&lt;/code&gt; you must specify an additional dash – &lt;code&gt;-%&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With the example above, the specific configuration option will be placed only if the fact &lt;code&gt;is_virtual&lt;/code&gt; evaluates true on a node.&lt;/p&gt;
&lt;p&gt;To see a complete example that incorporates facts and customized templates, download a module such as &lt;a href="https://forge.puppetlabs.com/puppetlabs/ntp"&gt;ntp&lt;/a&gt; from Puppet Forge and install it on the Puppet master with the command &lt;code&gt;puppet module install puppetlabs/ntp&lt;/code&gt;. You can then check the file /etc/puppet/modules/ntp/manifests/init.pp to see how different templates are used depending on the remote host operating system. After that check any of the files inside /etc/puppet/modules/ntp/templates/ to see what a complete template looks like.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/289652/Flexible-administration-with-Puppet-s-Facter-and-templates&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/mBu1SA3OeXA" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Thu, 09 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:289652</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/289652/Flexible-administration-with-Puppet-s-Facter-and-templates</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/287694/Knock-for-OpenSSH#Comments</comments><slash:comments>0</slash:comments><title>Knock for OpenSSH</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/EdtAX5MJAoI/Knock-for-OpenSSH</link><description>&lt;p&gt;If an attacker knows that your server is listening on a given port, potentially ready to allow entrance, he can target it for a security breach. An open port can be seen as a door to your system, and a password would be its key. But what would happen if the door were hidden, invisible, and you needed to use something special to make it visible again? A technique called port knocking keeps ports closed until users provide a secret knock sequence that only then allows them access to your site.&lt;/p&gt;
&lt;p&gt;It should be obvious that you can't use port knocking for a public service, because nobody would be able to use it. However, if you want to allow access to resources on your network to only a few people in the know, port knocking can help. The usual security methods, including passwords and certificates, are still mandatory, but they enter into play only after a user has provided the appropriate sequence of "knocks."&lt;/p&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;More secure OpenSSH&lt;/strong&gt;&lt;br&gt;&lt;a href="http://olex.openlogic.com/packages/openssh"&gt;OpenSSH&lt;/a&gt; is a well-known suite of security tools that comprises the utilities ssh, scp, sftp, and more. You should configure OpenSSH to be as safe as possible, in addition to using port knocking. Consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using a port other than the default port of 22, to give script kiddies a harder time.&lt;/li&gt;
&lt;li&gt;Disallowing root connections.&lt;/li&gt;
&lt;li&gt;Using certificates instead of passwords.&lt;/li&gt;
&lt;li&gt;Adding software such as &lt;a href="http://denyhosts.sourceforge.net/"&gt;DenyHosts&lt;/a&gt; to fight brute-force attacks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check the &lt;a href="http://www.openssh.org/manual.html"&gt;OpenSSH documentation&lt;/a&gt; for more information on how to use these features.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The main point behind hiding ports is that, even though ports in your firewall may be closed, you can still recognize an attempt at contacting them. Whenever the server recognizes a specific, secret sequence of attempts (an "open sesame!", if you will) it can open a port to let the outside user attempt logging in through OpenSSH. However, while the sequence is underway, the server sends no answer whatsoever to the remote user, making the listener itself undetectable. For extra safety, if a user takes too long, the port can be closed again. And after a user logs out, the port should also be closed. Finally, when the port is opened, it's only for the original user; other users won't be able to take advantage of the port if they do not provide the appropriate knock sequence.&lt;/p&gt;
&lt;p&gt;You can make the knock sequence as complex as you like, ranging from a simple list of ports (such as "try first TCP port 8000, then TCP port 8010, and finally TCP port 8006") to use of a list of one-time-only sequences, which are discarded after each use and never again accepted. (For cryptography buffs, this is equivalent to &lt;a href="http://en.wikipedia.org/wiki/One-time_pad"&gt;one-time pads&lt;/a&gt;, the most secure encryption method.) Given that there are more than 60,000 available ports (65,535 possible ports, less the ones already assigned), there are roughly 13 million million million port-knocking combinations for a hacker to try – brute-force methods won't help here! Of course, a proficient hacker might resort to more sophisticated methods, and that's why we say that you should never use port knocking as your only protection, but rather one more hoop for hackers to jump through.&lt;/p&gt;
&lt;h3&gt;Setting up port knocking&lt;/h3&gt;
&lt;p&gt;If you are good at iptables you can implement port knocking by yourself, but there's a ready-made alternative: the &lt;a href="http://www.zeroflux.org/projects/knock/"&gt;knockd daemon&lt;/a&gt;. If you use it you don't have to change any other settings or configurations; the daemon will work with the firewall, not interfering with OpenSSH. Knockd is available for all distributions; install it on any server you wish to protect. You'll have to edit a configuration file, /etc/knockd.conf (see below), possibly forward some ports from the firewall to your server (so knockd can recognize the attempts), and finally start knockd; that's it!&lt;/p&gt;
&lt;pre&gt;[options]
  interface= eth0  
  usesyslog
  logfile= /var/log/knockd.log
  pidfile= /var/run/knockd.pid

[opencloseSSH] 
  sequence= 8000,8010,8006
  tcpflags= syn 
  seq_timeout= 15 
  cmd_timeout= 30 
  start_command= /usr/sbin/iptables -s %IP% -I input_ext 1 -p tcp --dport 22 -j ACCEPT 
  stop_command= /usr/sbin/iptables -s %IP% -D input_ext -p tcp --dport 22 -j ACCEPT 
&lt;/pre&gt;
&lt;p&gt;The configuration file has an &lt;code&gt;options&lt;/code&gt; section with global parameters, and one or more additional sections, each of which defines a knocking sequence. Parameters include what interface to use (eth0 is the default), how to log events, and whether to provide a file with the PID of the knock program; if knockd were to crash, the system would be completely inaccessible from a remote location, so it's convenient to set up a cron task to use the &lt;code&gt;PidFile&lt;/code&gt; option to check if a restart is needed.&lt;/p&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;One-time sequences&lt;/strong&gt;&lt;br&gt;Always using the same sequence is a potential security problem. You can improve security by using one-time sequences – a list of sequences to be used only once and then erased. With this approach, even if an attacker learned a sequence, the system wouldn't be compromised. Check knockd's &lt;a href="http://linux.die.net/man/1/knockd"&gt;man page&lt;/a&gt; for more on this and other options.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each sequence must start with a name. Set a somewhat short time (15 seconds here) in which the sequence must be received; if all knocks aren't given in that time, everything goes back to zero. Set another timeout for the login attempt itself (30 seconds); again, if the remote user hasn't logged in in that time, all ports are closed again. When someone successfully provides the knock sequence, knockd runs the "start command"; in our case, opening port 22 (OpenSSH) but only for the IP address from which the knock attempts came, as specified by %IP%. When the connection is closed, the "stop command" gets things back to normal, closing port 22. You'll have to determine the appropriate iptables commands for your own setup; the ones shown here work fine on my openSUSE machine, but may differ for other distributions.&lt;/p&gt;
&lt;p&gt;The knockd program itself has a few options:&lt;/p&gt;
&lt;table summary="knocd options" cellspacing="0" cellpadding="0"&gt;&lt;caption&gt;Knockd options&lt;/caption&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-c&lt;/td&gt;
&lt;td&gt;What configuration file to use, instead of the standard /etc/knockd.conf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-d&lt;/td&gt;
&lt;td&gt;Run knockd in daemon mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-D&lt;/td&gt;
&lt;td&gt;Provide debugging output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-h&lt;/td&gt;
&lt;td&gt;Provide help on syntax and options&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-i&lt;/td&gt;
&lt;td&gt;Specify what interface to watch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-l&lt;/td&gt;
&lt;td&gt;Enable DNS lookup for log entries. This isn't a good idea, since it makes your server originate DNS traffic, thus losing stealthiness.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-v&lt;/td&gt;
&lt;td&gt;Be more verbose&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-V&lt;/td&gt;
&lt;td&gt;Show the program version&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;Port knocking in use&lt;/h3&gt;
&lt;p&gt;If you just close all ports, and don't run knockd, you won't be able to connect with OpenSSH:&lt;/p&gt;
&lt;pre&gt;ssh your.site.url -o ConnectTimeout=15 
ssh: connect to host your.site.url port 22: Connection timed out 
&lt;/pre&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Doing more work&lt;/strong&gt;&lt;br&gt;Knockd is generally used for opening and closing ports, but you can have it listen for different knock sequences and do jobs other than working with the firewall. The &lt;code&gt;start_command&lt;/code&gt; can be any script, so you are not limited in possible usages for port knocking!&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;However, if you start knockd (run either &lt;code&gt;sudo /etc/init.d/knockd start&lt;/code&gt; or &lt;code&gt;sudo knockd -d&lt;/code&gt;) then knock at the defined ports in order (8000, 8010, 8006) you will be able to log in. For knocking you can use the knock program, or you can make do with telnet instead, along the lines of &lt;code&gt;telnet your.site.url 8000&lt;/code&gt;; since telnet is usually available everywhere, you should never have any problems opening a remote port:&lt;/p&gt;
&lt;pre&gt;&amp;gt; knock your.site.url 8000 
&amp;gt; knock your.site.url 8010
&amp;gt; knock your.site.url 8006 
&amp;gt; ssh your.site.url -o ConnectTimeout=15
Password: 
&lt;/pre&gt;
&lt;p&gt;Port knocking allows you to raise the security level of your server by totally hiding even the fact that it could accept OpenSSH connections. It's a useful tool that can make hackers work harder, which is always better. On the down side, handling the security aspects of the knocking method can be a (minor) problem, and a hacker may recognize it by analyzing packet flows, so don't forget to make the rest of your system as safe as possible.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/287694/Knock-for-OpenSSH&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/EdtAX5MJAoI" height="1" width="1"/&gt;</description><dc:creator>Federico Kereki</dc:creator><pubDate>Mon, 06 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:287694</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/287694/Knock-for-OpenSSH</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/287685/Get-more-out-of-phpMyAdmin#Comments</comments><slash:comments>1</slash:comments><title>Get more out of phpMyAdmin</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/AYaZHA1ay54/Get-more-out-of-phpMyAdmin</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/phpmyadmin"&gt;phpMyAdmin&lt;/a&gt; is popular with both individuals and enterprise users who want a graphical interface for administering &lt;a href="http://olex.openlogic.com/packages/mysql"&gt;MySQL&lt;/a&gt; databases. Although the app has an &lt;a href="http://www.phpmyadmin.net/home_page/"&gt;expansive list of features&lt;/a&gt;, most people don't use it for much beyond basic tasks such as creating new databases. Here are some features tucked beneath phpMyAdmin's folds that can make you more efficient.&lt;/p&gt;
&lt;h3&gt;Manage users, check statistics&lt;/h3&gt;
&lt;p&gt;One of the most important tasks for a MySQL server administrator is to manage which users can access the database server. Although MySQL offers a flexible permissions system, mastering it isn't a trivial task.&lt;/p&gt;
&lt;p&gt;You can save yourself the hassle of constantly referring to the MySQL documentation by creating and managing users via phpMyAdmin. The Users tab gives you an overview of existing users and their privileges. From this section, you can add and delete users and employ a simple series of checkboxes to set and modify user privileges.&lt;/p&gt;
&lt;p&gt;MySQL's &lt;code&gt;SHOW STATUS&lt;/code&gt; command displays all aspects of the server along with statistics on network traffic and database queries. You can get ahold of this information and more via phpMyAdmin from the Status tab, which lists all the run-time information about the server. Under Status, the All status variables tab lets you browse through all the variables that the server tracks to assess things such as cache performance and memory usage. The Monitor tab shows all the statistics as live charts that can help you track down resource-intensive queries. The Advisor tab analyzes the different variables and provides recommendations to tune and optimize the server.&lt;/p&gt;
&lt;!-- pma-monitor.png --&gt;
&lt;h3&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/pma-monitor-resized-600.png" border="0" alt="pma monitor resized 600"&gt;&lt;/h3&gt;
&lt;h3&gt;Create a Control user&lt;/h3&gt;
&lt;p&gt;In addition to these features hidden in its graphical interface, phpMyAdmin also has some advanced features. For example, you can use phpMyAdmin to bookmark complex SQL queries and execute them later, or keep a log of executed queries, and even track changes made to tables and databases. To use these additional features you need to create a database known as the phpMyAdmin configuration storage or pmadb to store the configuration information for these additional features.&lt;/p&gt;
&lt;p&gt;But to administer this database, you first need to create a control user. The control user is a special MySQL user that's set up with limited permissions and only has read-only access to the user and db tables of the database named mysql.&lt;/p&gt;
&lt;p&gt;To create the user, head to phpMyAdmin's SQL tab, where you can run SQL queries on your server, or you can run the following commands from the shell using the MySQL command-line client. To use "pma" as the control user and "pmapass" as this user's password, run the commands:&lt;/p&gt;
&lt;pre&gt;GRANT USAGE ON mysql.* TO 'pma'@'localhost' IDENTIFIED BY 'pmapass';
GRANT SELECT (
    Host, User, Select_priv, Insert_priv, Update_priv, Delete_priv,
    Create_priv, Drop_priv, Reload_priv, Shutdown_priv, Process_priv,
    File_priv, Grant_priv, References_priv, Index_priv, Alter_priv,
    Show_db_priv, Super_priv, Create_tmp_table_priv, Lock_tables_priv,
    Execute_priv, Repl_slave_priv, Repl_client_priv
    ) ON mysql.user TO 'pma'@'localhost';
GRANT SELECT ON mysql.db TO 'pma'@'localhost';
GRANT SELECT ON mysql.host TO 'pma'@'localhost';
GRANT SELECT (Host, Db, User, Table_name, Table_priv, Column_priv)
    ON mysql.tables_priv TO 'pma'@'localhost';
&lt;/pre&gt;
&lt;p&gt;Finally, specify the details for the control user in phpMyAdmin's configuration file, config.inc.php, available under the directory you've installed the software in. Look for the strings that read &lt;code&gt;$cfg['Servers'][$i]['controluser']&lt;/code&gt; and &lt;code&gt;$cfg['Servers'][$i]['controlpass']&lt;/code&gt; and replace them with &lt;code&gt;$cfg['Servers'][$i]['controluser'] = 'pma';&lt;/code&gt; and &lt;code&gt;$cfg['Servers'][$i]['controlpass'] = 'pmapass';&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Enable configuration storage&lt;/h3&gt;
&lt;p&gt;After you create the control user you need to create a special database to store the settings for the phpMyAdmin configuration storage, and ensure that this database can be accessed only by the control user.&lt;/p&gt;
&lt;p&gt;To create the database, change into the script/ or examples/ directory inside phpMyAdmin's install directory; you'll have one or the other depending on how you have installed phpMyAdmin. Look for a file called create_tables.sql. If you're running a more recent version than MySQL version 4.1.2, first run &lt;code&gt;mysql &amp;lt; upgrade_tables_mysql_4_1_2+.sql&lt;/code&gt;, then import create_tables.sql into your MySQL server with the command &lt;code&gt;mysql &amp;lt; create_tables.sql&lt;/code&gt;. This will create a database called "phpmyadmin" with tables for each feature.&lt;/p&gt;
&lt;p&gt;Next, allow the control user to make changes to this database. You can either do this graphically via phpMyAdmin Users tab or enter the following SQL command:&lt;/p&gt;
&lt;pre&gt; GRANT SELECT, INSERT, UPDATE, DELETE ON phpmyadmin.* TO 'pma'@'localhost'; &lt;/pre&gt;
&lt;p&gt;To enable an advanced feature, such as the query bookmark feature, you need to specify the name of the table that controls that feature in config.inc.php. To do that, first specify the name of the configuration storage database by hunting for the string &lt;code&gt;$cfg['Servers'][$i]['pmadb']&lt;/code&gt; and replacing it with &lt;code&gt;$cfg['Servers'][$i]['pmadb'] = 'phpmyadmin';&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now if you wish to use the bookmark function, enter the bookmarktable name in &lt;code&gt;$cfg['Servers'][$i]['bookmarktable']&lt;/code&gt; such as &lt;code&gt;$cfg['Servers'][$i]['bookmarktable'] = 'pma_bookmark';&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Browse the phpmyadmin database and make sure you enter the correct table name in the configuration file, then log out and log into phpMyAdmin again to bring the new configuration into effect.&lt;/p&gt;
&lt;h3&gt;Track changes&lt;/h3&gt;
&lt;p&gt;After activating the phpMyAdmin configuration storage mechanism you should enable the track changes feature, which keeps track of every phpMyAdmin-executed MySQL command. You can then create multiple versions of individual tables. You can create a version of a table, for example, before you manipulate its data, so that you have a reliable copy to revert to in case the changes corrupt the table. Each version is a snapshot of the table and logs all data manipulation statements (such as INSERT, UPDATE, and DELETE) and data definition statements (such as CREATE, DROP, and ALTER) and links these commands with the version number.&lt;/p&gt;
&lt;p&gt;To enable the tracking mechanism, edit the config.inc.php file and replace the &lt;code&gt;$cfg['Servers'][$i]['tracking']&lt;/code&gt; string with &lt;code&gt;$cfg['Servers'][$i]['tracking'] = 'pma_tracking';&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After the feature has been enabled you'll get an additional Tracking tab when browsing a database. When you click on the tab you can select which data definition and manipulation statements you'd like to track for that particular table.&lt;/p&gt;
&lt;!-- pma-track.png --&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/pma-track-resized-600.png" border="0" alt="pma track resized 600"&gt;&lt;/p&gt;
&lt;p&gt;After you've enabled tracking for a table and created a version, the tracking page will show all versions for all tables. From here you can also view a complete report for every version. You can revert any table to a specific version.&lt;/p&gt;
&lt;h3&gt;Securing phpMyAdmin&lt;/h3&gt;
&lt;p&gt;While you might have gone to great lengths to &lt;a href="http://dev.mysql.com/doc/refman/5.5/en/mysql-secure-installation.html"&gt;secure your MySQL server&lt;/a&gt; and &lt;a href="http://www.openlogic.com/wazi/bid/188105/How-to-Secure-Your-Apache-Web-Server"&gt;secure your web server&lt;/a&gt;, it all comes to naught if you haven't secured phpMyAdmin.&lt;/p&gt;
&lt;p&gt;The good news is that securing phpMyAdmin doesn't take much effort. phpMyAdmin supports a variety of &lt;a href="http://wiki.phpmyadmin.net/pma/Auth_types"&gt;authentication methods&lt;/a&gt;. If you use the simple "config" authentication type, anyone with the URL of your phpMyAdmin can log in without a password and have the same rights to your data as you! This authentication mechanism works best if your server is behind a firewall or you limit access to the data using your &lt;a href="http://www.openlogic.com/wazi/bid/188035/Smart-Access-Control-with-Apache"&gt;web server's access mechanisms, such as Apache's .htaccess&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you use the "cookie" authentication type (which is the default authentication mechanism), only authentic MySQL users can access the phpMyAdmin interface. There's also "http" authentication, which prompts for a MySQL username and password but only uses basic HTTP access authentication, and the "signon" authentication, to integrate phpMyAdmin with &lt;a href="http://www.wikipedia.org/wiki/Single_sign_on"&gt;single sign-on&lt;/a&gt; systems.&lt;/p&gt;
&lt;p&gt;Another way to secure phpMyAdmin is to block access to it by constructing rules that allow or deny access after verifying the IP address of the machine from which the request is received. To enable this option, edit the config.inc.php configuration file. Look for the host authentication order string &lt;code&gt;$cfg['Servers'][$i]['AllowDeny']['order'] = 'allow,deny';&lt;code&gt;. This denies access to everyone except for the users you've allowed in the authentication rules.&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Or you can change the order to &lt;code&gt;$cfg['Servers'][$i]['AllowDeny']['order'] = 'deny,allow';&lt;code&gt;, which tells MySQL to apply all deny rules first, followed by allow rules. If a case is not mentioned in the rules, then access will be granted. Then, to block a user from logging into phpMyAdmin, look for host authentication rules, and change it to read:&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;$cfg['Servers'][$i]['AllowDeny']['rules'] = array(
'deny &lt;em&gt;some_user&lt;/em&gt; from all',
);
&lt;/pre&gt;
&lt;p&gt;This will deny access to the user called &lt;em&gt;some_user&lt;/em&gt;. You can specify a list of rules to allow only a very limited number of users (even ones from remote hosts) while denying access to the rest (including some from local hosts).&lt;/p&gt;
&lt;p&gt;Another important aspect to securing phpMyAdmin is to deny access to the almighty root user. To prevent the root user from logging into phpMyAdmin, add this line to the configuration file: &lt;code&gt;$cfg['Servers'][$i]['AllowRoot'] = FALSE;&lt;code&gt;.&lt;/code&gt;&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;Backup databases&lt;/h3&gt;
&lt;p&gt;Although taking &lt;a href="http://www.openlogic.com/wazi/bid/273437/Three-simple-tools-for-backing-up-MySQL-databases"&gt;backups of databases&lt;/a&gt; is no easy task, you can use phpMyAdmin to easily take a snapshot of a database or individual tables and export them in more than a dozen formats, including CSV, Open Document, Excel, JSON, YAML, and PDF.&lt;/p&gt;
&lt;p&gt;To export a database, head to the Export tab. By default the Quick export mode is toggled, which exports all the databases from the current server in the format you select from the pull-down list. If you switch to the Export tab after selecting a database, the Quick export mode allows you to select the tables you want to export (by default all are selected) in addition to the export format.&lt;/p&gt;
&lt;p&gt;If you want more control over the export process, select the Custom export method under the Export tab. This gives you lots of choices, including the option to compress the output, export just the table structures, just the data, or both, and a lot more.&lt;/p&gt;
&lt;p&gt;phpMyAdmin packs in a lot of functionality. I hope these tips help you exploit the tool to its full potential.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/287685/Get-more-out-of-phpMyAdmin&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/AYaZHA1ay54" height="1" width="1"/&gt;</description><dc:creator>Mayank Sharma</dc:creator><pubDate>Thu, 02 May 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:287685</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/287685/Get-more-out-of-phpMyAdmin</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/285446/Image-annotation-in-GIMP-Dia-and-OpenOffice-Draw#Comments</comments><slash:comments>2</slash:comments><title>Image annotation in GIMP, Dia, and OpenOffice Draw</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/cD_5d5s8l7U/Image-annotation-in-GIMP-Dia-and-OpenOffice-Draw</link><description>&lt;p&gt;The &lt;a href="http://olex.openlogic.com/packages/gimp"&gt;GIMP&lt;/a&gt; is a wonderful image editor, but it might be overkill if all you want to do is annotate an image. If you want to highlight a part of an image, so that for example the audience for your presentation can focus on a particular aspect, you'll probably find it easier and more intuitive to do that in a program such as &lt;a href="http://sourceforge.net/projects/dia-installer/"&gt;Dia&lt;/a&gt; or &lt;a href="http://olex.openlogic.com/packages/openoffice"&gt;OpenOffice&lt;/a&gt; Draw. Let's see how to annotate an image in all three programs.&lt;/p&gt;
&lt;p&gt;As an example, we'll highlight an image by circling an area and creating an arrow to point at the circle. All three of the tools mentioned allow you to work in different layers, separating the edits of the background from the annotations. We'll work with an &lt;a href="http://commons.wikimedia.org/wiki/File:Arms_of_All_Nations_by_Boston_Public_Library.jpg"&gt;image of coats of arms&lt;/a&gt; that dates from 1876, and highlight the coat of arms for Siam (Thailand), which shows an elephant. You could ask an audience to count down four rows and over two columns, but if you draw a circle around the item, the audience can quickly find it immediately.&lt;/p&gt;
&lt;p&gt;With the image loaded in the GIMP, drill down through the menu using Tools -&amp;gt; Selection Tools -&amp;gt; Ellipse Select. Click with the mouse at the top left of the Siam entry and then again at the bottom right. This creates a "marching ants" outline for the circle. Using Windows -&amp;gt; Dockable Dialogs -&amp;gt; Colors set the foreground (drawing) color to a distinctive color to make the circle stand out against the image.&lt;/p&gt;
&lt;p&gt;Choose Edit -&amp;gt; Stroke Selection to change line parameters. Choose "Stroke line" to begin testing, with a width of 3 px. It will use the current foreground color and draw a line of the thickness you specify where the marching ants are. You should now have a red circle around the Siam coat of arms. Choose Select -&amp;gt; none to cancel the circle selection. The marching ants will stop and your circle will remain in place.&lt;/p&gt;
&lt;p&gt;To draw an arrow, choose Tools -&amp;gt; Paint Tools -&amp;gt; Pencil or Brush. Set the properties of the drawing tool to suit your purposes. The result should be something like Figure 1.&lt;/p&gt;
&lt;!-- Figure 1: Circle and arrow in the GIMP --&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/Fig 1-resized-600.jpg" border="0" alt="Circle and arrow in the GIMP"&gt;&lt;/p&gt;
&lt;p&gt;One of the drawbacks of using the GIMP is that the result is not easily editable. You can edit the circle and arrow as a bunch of pixels separate from the underlying image if you paint them onto their own separate layer, but any advanced editing, such as moving the arrow relative to the circle or changing its color, unless each is on its own layer, is not easy.&lt;/p&gt;
&lt;h3&gt;Annotation in Dia&lt;/h3&gt;
&lt;p&gt;Now let's attempt the same thing using Dia. Load the image into the main Dia window, then select the ellipse or perfect circle object from the diagram editor and click it onto the base image. Figure 2 shows the initial result of this operation.&lt;/p&gt;
&lt;!-- Figure 2: Dragging a circle onto the image in Dia --&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/Fig 2-resized-600.jpg" border="0" alt="Dragging a circle onto the image in Dia"&gt;&lt;/p&gt;
&lt;p&gt;You can use the eight green points to adjust the position and size of the circle over the correct part of the large image. You can also click and drag as needed.&lt;/p&gt;
&lt;p&gt;Next, right-click on the circle and choose Properties from the dialog box. Here you can change the color of the circle and its line width. Change "Draw background" to NO; this controls opacity, and the background it refers to is the white background of the circle object. Saying no allows the coat of arms image to show through. In Dia, opacity of objects is either 0 percent or 100; if you need more varied opacity then you should choose a different editor.&lt;/p&gt;
&lt;p&gt;At this point you have two objects, the circle and the base image, both sitting on one layer. Since they are both on the same layer, Dia may try to associate them. You may not notice an effect now, but when you add an arrow, Dia will probably try to associate the arrow with the base image. If you see some strange behavior where you cannot place the end of an arrow where you want it, you should remove your objects from the layer, add a new layer through the Layer menu option, and paste the objects onto the new layer. Dia now will not try to associate the annotations with the underlying image if they are on different layers, but will associate them with each other, which is what you want.&lt;/p&gt;
&lt;p&gt;To add an arrow, click the line object from the diagram editor palette and click again somewhere in the image outside the circle. This produces a line with an arrowhead. Click on the ends to adjust its position. Dragging the arrow end into the circle lights up the circle to show that the program recognizes that the circle and the arrow should be associated. Release the mouse button and you'll find that the arrow is now connected to the circle.&lt;/p&gt;
&lt;p&gt;The two objects can now be treated as a group or separately. If you drag or resize the circle, the arrow will follow it. You can edit each object by selecting it and right-clicking to produce the dialog box.&lt;/p&gt;
&lt;p&gt;Figure 3 shows a detail view of the final output. Note that at high resolution there is a little bleeding of the lines into the base image. This would not be noticeable at a distance; the thinner the lines, the worse the bleeding.&lt;/p&gt;
&lt;!-- Figure 3: Detail of image in Dia --&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/Fig 3-resized-600.jpg" border="0" alt="Detail of image in Dia"&gt;&lt;/p&gt;
&lt;p&gt;If you export this set of objects as an image, Dia will not preserve the object structure. Make sure to save the structure as a Dia file if you need to come back and edit the objects separately.&lt;/p&gt;
&lt;h3&gt;Annotation in OpenOffice Draw&lt;/h3&gt;
&lt;p&gt;OpenOffice Draw, which is just as intuitive as Dia, uses a similar process. You can easily select objects once they have been created, and change their properties at any time. Draw does not have the same library of technical shapes Dia comes with, but it is quite capable with more general shapes.&lt;/p&gt;
&lt;p&gt;Also, Draw does not associate or connect objects; that is up to the drawer. In some cases it is more efficient and effective to allow a program such as Dia do this, since the result will usually look more professional, and it makes subsequent editing easier.&lt;/p&gt;
&lt;p&gt;In Draw, add a circle in the same way as in Dia, by selecting one of the standard objects. You can add an arrow either by placing a plain line and then editing the line to show an arrow at one end, or select an object from the Arrow tool box, which you can make viewable from the View -&amp;gt; Toolbars menu item.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/Fig 4-resized-600.jpg" border="0" alt="The result in OpenOffice Draw"&gt;&lt;/p&gt;
&lt;!-- Figure 4: The result in OpenOffice Draw --&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;When you need to annotate images, clearly you have a choice of tools from which you can pick. The GIMP is the way to go if you want to learn just one application that provides all the bells and whistles required to edit your base image as well as add annotation. However, the GIMP does not treat annotations as objects that can be linked together, so it is not easy to edit annotations once they have been created, but you can build them in layers and delete and recreate layers as needed. Also, the GIMP's menu structure is quite complicated; remembering the steps and which menu is where is a challenge unless you are a regular user of the program.&lt;/p&gt;
&lt;p&gt;Dia is a good choice if you need to make basic adjustments to an image and need access to a library of technical object shapes to add to your exposition. Most of Dia's commands and buttons are readily visible.&lt;/p&gt;
&lt;p&gt;OpenOffice Draw is an excellent midpoint between the GIMP and Dia. It creates annotations as objects as in Dia, but lacks Dia's library of technical object shapes. It does however have a large gallery of fills, which, while not relevant in this case since the background is part of the presentation, would be helpful in a more general context.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/285446/Image-annotation-in-GIMP-Dia-and-OpenOffice-Draw&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/cD_5d5s8l7U" height="1" width="1"/&gt;</description><dc:creator>Colin Beckingham</dc:creator><pubDate>Mon, 29 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:285446</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/285446/Image-annotation-in-GIMP-Dia-and-OpenOffice-Draw</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/285127/Solr-Drupal-7-and-faceted-search#Comments</comments><slash:comments>0</slash:comments><title>Solr, Drupal 7, and faceted search</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/iau-3d_TSfU/Solr-Drupal-7-and-faceted-search</link><description>&lt;p&gt;It's easy to get started with the search server &lt;a href="http://olex.openlogic.com/packages/solr"&gt;Apache Solr&lt;/a&gt; and the popular CMS platform &lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, as described in &lt;a href="http://www.openlogic.com/wazi/bid/283711/How-to-set-up-Solr-4-2-on-Drupal-7-with-Apache"&gt;our previous tutorial on setting up Solr 4.2 with Drupal 7&lt;/a&gt;. Straight out of the box Solr handles basic text searching, but you can increase its power by adding faceted search – the ability to filter on specific facets or aspects of the data on a site. For example, on a Drupal site you might want to be able to filter your searching by author, date, or tags. Solr's faceted search allows users to combine this type of filtering with text searching to find the information they're after faster. Read on for the lowdown on setting up and configuring basic faceted search using Solr 4.2 and Drupal 7, running on &lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt; on Linux.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://drupal.org/project/facetapi"&gt;Facet API module for Solr on Drupal&lt;/a&gt; will get you set up with faceted search. It doesn't come by default with the Solr Drupal module; you have to install it independently. You can download it from the website and install it manually into sites/all/modules in your Drupal install, or install it using &lt;a href="http://drupal.org/project/drush"&gt;Drush&lt;/a&gt;, a command-line interface to Drupal. Drush is worth installing if you have more than one or two modules on your site, as it makes it quicker to work with them from the command line. To get Facet API running, you also need to install its dependency, the &lt;a href="http://drupal.org/project/ctools"&gt;Chaos Tools&lt;/a&gt; module. From the command line (as root/sudo) type:&lt;/p&gt;
&lt;pre&gt;drush dl facetapi 
drush dl ctools
&lt;/pre&gt;
&lt;p&gt;Once the modules are installed, go to the Drupal admin console and click the Modules tab (http://localhost/?q=admin/modules). Select Chaos Tools in the Chaos Tools Suite section, and Current Search Blocks and Facet API in the Search section, then click Save Configuration.&lt;/p&gt;
&lt;p&gt;To configure the facets you want users to be able to search on, go to the Apachesolr module configuration on Drupal (http://localhost/?q=admin/config/search/apachesolr/settings) and click the Facets link next to localhost. You'll see the list of default facet blocks that you can enable: author, content type, language, post date, tags, and update date. Enable only the ones that you wish to have available to users, because facet indexing requires system resources, and indexing facets that you won't use may adversely affect system performance.&lt;/p&gt;
&lt;!-- img src="solr_facets_enable.png" /--&gt;
&lt;h3&gt;&lt;img id="img-1366215017022" src="http://www.openlogic.com/Portals/172122/images/solr_facets_enable-resized-600.png" border="0" alt="solr facets enable resized 600"&gt;&lt;/h3&gt;
&lt;p&gt;Once you've enabled the facets, if you reload the http://localhost/?q=admin/config/search/apachesolr/settings page, you should see a configuration drop-down link next to each enabled facet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;b&gt;Configure display&lt;/b&gt;&lt;/em&gt; controls how the facet links show up on the search page (as links or links with checkboxes, which can help users keep track of what they're searching on), how they are sorted, and whether you use AND or OR when applying this facet.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;b&gt;Configure dependencies&lt;/b&gt;&lt;/em&gt; controls under what circumstances the facet is shown. You can hide facets on pages or articles, or when specific users are logged in.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;b&gt;Configure filters&lt;/b&gt;&lt;/em&gt; controls whether certain items are shown, and how many levels are displayed for multilevel facets such as tags.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;b&gt;Export configuration&lt;/b&gt;&lt;/em&gt; shows you the code associated with the current configuration so you can save it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Set these up to meet the needs of your specific site and save the configuration. You can then go to the search page and see how your settings appear. At this point they'll only show up on the search page, so you can filter your search results once they come back. Try them out to make sure everything is working as expected.&lt;/p&gt;
&lt;h3&gt;Showing facets outside of search pages&lt;/h3&gt;
&lt;p&gt;What if you want facets and facet search to show on non-search pages? For example, many sites show a tag cloud or dates of articles in a sidebar. These are both examples of faceted search, and you can use Facet API and Solr to set them up for your Drupal site.&lt;/p&gt;
&lt;p&gt;To show facets on all pages, go back to the Facets settings admin page (http://localhost/?q=admin/config/search/apachesolr/settings/solr/facets) and click "Show facets on non-search pages." You'll then see a box that allows you to enter the &lt;a href="http://drupal.org/node/31644"&gt;paths&lt;/a&gt; of the pages on which you want facets to be displayed. Note, however, that you cannot just use * to display facets on all paths; this leads to &lt;a href="http://stackoverflow.com/questions/14193054/drupal-solr-is-indexing-but-not-showing-any-search-results"&gt;a bug&lt;/a&gt; where faceted searches will fail with no results. Instead, you need to list specific paths. A good starting point is:&lt;/p&gt;
&lt;pre&gt;node
node/* 
user/*
&lt;/pre&gt;
&lt;p&gt;This will cover the default front page (&lt;code&gt;node&lt;/code&gt;), all pages and articles (&lt;code&gt;node/*&lt;/code&gt;), and all user pages (&lt;code&gt;user/*&lt;/code&gt;). You may of course wish to add other paths for your site; just don't add &lt;code&gt;search/*&lt;/code&gt; or you'll run into the same bug!&lt;/p&gt;
&lt;p&gt;Once you've enabled the facets, you need to decide where to display them on the page; until you do they won't be visible. Go to the Blocks admin page (http://localhost/?q=admin/structure/block/) and scroll down to the Disabled section, then click Configure for each facet you wish to display, and choose where you wish to display each facet. You could, for example, put all your enabled facet searches in the second sidebar. Save the configuration, then check your site to see the new facets in the place you've chosen to display them.&lt;/p&gt;
&lt;h3&gt;Other facet-related modules&lt;/h3&gt;
&lt;p&gt;A lot of sites these days show tags as a cloud rather than as a list, where the font size of each tag increases along with how often it appears. The &lt;a href="http://drupal.org/project/facetapi_tagcloud"&gt;facetapi_tagcloud&lt;/a&gt; Drupal module allows you to display your Solr facets this way. Install it manually or with Drush, and enable it from the Modules admin page. Then go to the Facet configuration page, click on tag (http://localhost/?q=admin/config/search/facetapi/apachesolr%40solr/block/im_field_tags/edit), and choose "Tagcloud links" as the display widget. Note that this module is in beta, so use with care.&lt;/p&gt;
&lt;p&gt;Another interesting module, &lt;a href="http://drupal.org/project/facetapi_multiselect"&gt;facetapi_multiselect&lt;/a&gt;, which gives you a multi-select view for faceted search, is unfortunately not yet available as a recommended release for Drupal 7. You could however download the development release and try that at your own risk.&lt;/p&gt;
&lt;p&gt;You might also consider building your own facets if the built-in ones don't meet the needs of your site. Unfortunately the module &lt;a href="http://drupal.org/project/apachesolr_facetbuilder"&gt;apachesolr_facetbuilder&lt;/a&gt;, which allows you to build facets without writing code, isn't available for Drupal 7 (and doesn't appear as if it's being updated) so you'll have to dig into the code to do this. The built-in facets, though, are good enough to meet the needs of many Drupal sites, so take the time to get them set up!&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/285127/Solr-Drupal-7-and-faceted-search&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/iau-3d_TSfU" height="1" width="1"/&gt;</description><dc:creator>Juliet Kemp</dc:creator><pubDate>Thu, 25 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:285127</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/285127/Solr-Drupal-7-and-faceted-search</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/284942/Using-FreeNAS-new-full-disk-encryption-for-ZFS#Comments</comments><slash:comments>0</slash:comments><title>Using FreeNAS' new full disk encryption for ZFS</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/D495rTMy4zg/Using-FreeNAS-new-full-disk-encryption-for-ZFS</link><description>&lt;p&gt;Last month's release of &lt;a href="http://olex.openlogic.com/packages/freenas"&gt;FreeNAS&lt;/a&gt; 8.3.1 adds new functionality that allows system administrators of the open source-based network attached storage solution to encrypt entire disks while using ZFS. ZFS has been the primary filesystem for FreeNAS since FreeNAS 8, and has supplanted FreeBSD's UFS as the project's focus. The new security functionality applies only to ZFS and is the first time that FreeNAS has supported encryption.&lt;/p&gt;
&lt;p&gt;Why use disk encryption? Modern operating systems such as FreeBSD, which is at the heart of FreeNAS, are designed to protect against unauthorized data access, and if you employ a good security policy, it should be hard for outside attackers to gain access to sensitive data stored under FreeBSD. If an attacker has physical access to a server, however, he can remove a disk from a server, take it away, and examine it at will – but not if it's encrypted.&lt;/p&gt;
&lt;p&gt;There is also the problem of disposing of obsolete or failed disks that contain sensitive data. Unless you physically break it (which some companies do) there is always a risk that someone could extract data from a discarded device – unless it's encrypted.&lt;/p&gt;
&lt;p&gt;With encryption enabled, all the data written to a disk is inaccessible without the right credentials. The newest security features in the latest version of FreeNAS support full-disk encryption, meaning that the encryption is done at the disk level, below the ZFS filesystem. FreeNAS employs GELI, a block device-layer disk encryption subsystem written for FreeBSD, which makes it more efficient than any add-on encryption tools would be.&lt;/p&gt;
&lt;h3&gt;Considerations&lt;/h3&gt;
&lt;p&gt;Before you use FreeNAS' new disk encryption facilities, you should understand a few important things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The disk encryption in FreeNAS 8.3.1 and later is not the same as the disk encryption designed by Oracle in ZFS v30. This means that you cannot import encrypted volumes from systems running Oracle's ZFS into FreeNAS.&lt;/li&gt;
&lt;li&gt;If you lose or forget the master key for your encrypted disk, all the data on the disk will be irretrievable.&lt;/li&gt;
&lt;li&gt;Encrypting data in the fly can be costly in terms of performance. Intel, in its i5 and i7 CPUs, and AMD, in its Bulldozer and Piledriver cores, have added a new AES encryption instruction set to &lt;a href="http://ark.intel.com/search/advanced/?s=t&amp;amp;AESTech=true"&gt;some of their processors&lt;/a&gt;. Without these AES instructions you will suffer an approximate 20 percent performance hit – more if you have multiple disks.&lt;/li&gt;
&lt;li&gt;You cannot convert an existing unencrypted volume into an encrypted one. To encrypt the data from an existing volume, you must back it up and restore it to a drive that has encryption enabled.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Getting started&lt;/h3&gt;
&lt;p&gt;To use disk encryption you need to be running at least FreeNAS 8.3.1-RELEASE-p2 – that is, the second patched version of the initial 8.3.1 release, which had a few problems. The FreeNAS site has good &lt;a href="http://doc.freenas.org/index.php/Main_Page"&gt;documentation&lt;/a&gt;, including a step-by-step installation guide.&lt;/p&gt;
&lt;p&gt;After installation you administer FreeNAS via a web interface. To create an encrypted volume, drill down through the tree menu on the left side of the web UI Storage -&amp;gt; Volumes -&amp;gt; Volume Manager. Select the disks you want to use to form the pool, select ZFS, and ensure that "Enable full disk encryption" is checked. There is also the option to initialize the disk with random data, which is useful if the disk was previously used.&lt;/p&gt;
&lt;p&gt;If you are using more than one disk, select the type of volume they should comprise: stripe, mirror, or &lt;a href="https://blogs.oracle.com/bonwick/entry/raid_z"&gt;RAID-Z&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Striping doesn't offer any redundancy but does improved performance. It is the equivalent of RAID-0, but it isn't generally recommended, as the failure of a single disk would result in the loss of all the data on the volume.&lt;/li&gt;
&lt;li&gt;Mirroring is the same as RAID-1. All the data is duplicated exactly onto one or more drives.&lt;/li&gt;
&lt;li&gt;RAID-Z needs at least three drives and offers the best trade-off between performance and redundancy. Data is shared among all the drives, and the volume will survive a disk failure.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you create a volume you must set a passphrase for the master key. Click the Create Passphrase button (the first icon with a key on it) and enter the passphrase. It can contain spaces, and can be a sentence or phrase and not necessarily just a word.&lt;/p&gt;
&lt;p&gt;It is prudent to create a recovery key so that in case you forget the passphrase you can use the associated recovery key instead. When you click the "Add recovery key" icon FreeNAS generates a recovery key and pushes the key file to you via the browser.&lt;/p&gt;
&lt;p&gt;You should also download a backup copy of the master key by clicking the Download Key icon. The GELI configuration is separate from the FreeNAS configuration, and it is best to have a backup copy in case the GELI key information is ever lost or destroyed. If, for example, you ever need to reinstall FreeNAS, due perhaps to a failure of the operating system disk, you can use the backup master key to gain access to the existing disks. Without the backup, you'd lose the encryption key information if the operating system disk failed.&lt;/p&gt;
&lt;p&gt;Whenever you reboot the FreeNAS server you will need to enter the passphrase before you can access the encrypted volume. Click Storage -&amp;gt; Volumes -&amp;gt; View Volumes, click the unlock icon (the only key-type icon shown), enter the passphrase, and ensure that the relevant network access services (such as CIFS and NFS) are marked for restart so that the volume becomes available to those services. If you forget the passphrase you can use the recovery key by uploading it instead of entering the passphrase. In such situations you should reset the passphrase by clicking on the Change Passphrase icon, in place of the Create Passphrase icon, and regenerating the recovery key.&lt;/p&gt;
&lt;p&gt;Here's something to watch out for: Locked volumes are available to the volume manager for use in new volumes. This lets you reuse previously encrypted disks when necessary, but it also mean that these volumes could be destroyed by mistake. It can seem a little disconcerting to see, considering that the volumes contain valuable data! Once a volume is unlocked its disks are no longer available to the volume manager, so you should unlock the volumes as soon as you can.&lt;/p&gt;
&lt;p&gt;It should almost go without saying that you must protect the passphrase, master key, and recovery key. If an attacker is able to physically access the disks and also has in his possession the passphrase or the recovery key, your encryption is rendered useless.&lt;/p&gt;
&lt;h3&gt;Replacing a failed encrypted disk&lt;/h3&gt;
&lt;p&gt;The ZFS mirror and RAID-Z options provide disk redundancy and let the filesystem survive the failure of a single hard disk in a volume. If a hard disk fails, click the Volume status icon on the View Volumes page, then take the disk offline by clicking Offline for the faulty disk. Physically replace the failed disk; depending on the hot-swap capabilities of your hardware, you may need to shut down FreeNAS to do this. On the View Volumes page click Replace next to the disk that has been changed and select the new disk. Enter the encryption passphrase for the volume – without the passphrase you cannot replace the disk.&lt;/p&gt;
&lt;p&gt;You cannot use the recovery key when you're replacing a disk. If you lose the passphrase and a disk fails, the only option is to use the recovery key to unlock the degraded volume, then change the passphrase before replacing the disk.&lt;/p&gt;
&lt;h3&gt;Extending an encrypted volume&lt;/h3&gt;
&lt;p&gt;One of the many advantages of the ZFS filesystem is that it lets you extend volumes by simply adding disks. Due to the nature of ZFS you can't increase the number of disks in an existing set, but instead you need to add more disks to the volume itself. For example, the way to expand a volume made up of three disks in a RAID-Z configuration is to add another three disks also working in RAID-Z. The result will be a volume with two sets of RAID-Z disks. The extra disks don't alter the original RAID-Z disks but rather expand the volume. It isn't possible to add a forth disk to the existing three.&lt;/p&gt;
&lt;p&gt;The advantage of this approach is that you can add disks of different sizes than the original disks to a volume. The disadvantage is that you cannot mix different configurations. In other words, you can expand a volume using RAID-Z only by adding another set of disks in a RAID-Z configuration, and so on.&lt;/p&gt;
&lt;p&gt;The same behavior applies when adding disks to an encrypted pool, but with the added complication that adding disks removes the existing encryption; you have to generate the passphrase and recovery key afresh once the new disks have been added.&lt;/p&gt;
&lt;p&gt;To add new disks to a volume, use the Volume Manager page. Select new member hard disks, matching the existing configuration – stripe, mirror, or RAID-Z array – and choose the volume to extend. The user interface will automatically select the filesystem type and disable the volume name field (since the volume already has a name and is just being extended). Click Extend Volume to get the FreeNAS volume manager to add the new hard disk (or disks) into the existing pool.&lt;/p&gt;
&lt;p&gt;Once you've added the disks, click on the Create passphrase icon and enter a passphrase to reestablish encryption, download the master key as a backup, and create a recovery key.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Encryption can guard against situations where an attacker physically gets hold of a hard disk. When used with a CPU that supports the AES instruction set encryption costs just a negligible performance impact. The FreeNAS implementation, although new, uses the proven FreeBSD disk encryption subsystem and a web-based UI that grants easy access to its functionality. But remember, you must guard the keys because, just like in the real world, if a thief has keys then he has full access.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/284942/Using-FreeNAS-new-full-disk-encryption-for-ZFS&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/D495rTMy4zg" height="1" width="1"/&gt;</description><dc:creator>Gary Sims</dc:creator><pubDate>Mon, 22 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:284942</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/284942/Using-FreeNAS-new-full-disk-encryption-for-ZFS</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/284663/Create-distributed-storage-with-Gluster#Comments</comments><slash:comments>0</slash:comments><title>Create distributed storage with Gluster</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/GIiRoIF3klk/Create-distributed-storage-with-Gluster</link><description>&lt;p&gt;If you're looking for Linux-based, hardware-agnostic storage software, check out &lt;a href="http://olex.openlogic.com/packages/gluster"&gt;Gluster&lt;/a&gt;, an open source project for creating a distributed filesystem. It provides fast performance, high availability, and horizontal scalability by spreading storage volumes over redundant cluster nodes. Here's how you can build a Gluster distributed storage system yourself.&lt;/p&gt;
&lt;p&gt;Gluster's storage is build up by what it calls bricks, which are exported directories allocated on the cluster nodes. Cluster nodes are united in trusted pools that together provide storage services and share disk resources.&lt;/p&gt;
&lt;p&gt;Gluster doesn't require any special hardware. You need at least two servers to act as nodes in the filesystem, to provide redundancy and make use of Gluster's essential features for performance and recovery. Each node must have at least 1GB of RAM; having more RAM may allow you to provide in-memory caching for the storage, thus speeding the I/O operations. Each node needs at least 1Gbps network connectivity and at least two disks – one for the operating system and one more for the storage. The higher the I/O speed of the media, of course, the better storage performance. Gluster runs best on &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt; but is also supported on other 64-bit Linux distributions. No 32-bit distributions are supported.&lt;/p&gt;
&lt;p&gt;Install Gluster from its own yum repository, which always provides the latest Gluster version. First, download Gluster's repository with the command &lt;code&gt;wget -P /etc/yum.repos.d http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo&lt;/code&gt;. This command places the repo file in the directory /etc/yum.repos.d/, thus enabling the repo.&lt;/p&gt;
&lt;p&gt;Now you can install the packages glusterfs-fuse, the userspace program for managing GlusterFS, and glusterfs-server, the server daemon, with the command &lt;code&gt;yum install glusterfs{-fuse,-server}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Finally, start Gluster's daemon for the first time with the command &lt;code&gt;service glusterd start&lt;/code&gt;. To make it start and stop automatically with the system, run the command &lt;code&gt;chkconfig glusterd on&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Follow the same process on each Gluster server.&lt;/p&gt;
&lt;h3&gt;Configure the network and the firewall&lt;/h3&gt;
&lt;p&gt;For optimal performance and security you should run the Gluster cluster inside a private and secured network. In such a network you can disable the default CentOS firewall because the network should be accessible only by trusted clients. To do this, use the command &lt;code&gt;chkconfig iptables off &amp;amp;&amp;amp; service iptables stop&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you cannot provide a private network for the storage cluster, you can use iptables to allow only predefined clients to access Gluster's services. To do so, allow the following with iptables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RPC incoming connectivity – Gluster's processes communicate using &lt;a href="http://en.wikipedia.org/wiki/Remote_procedure_call"&gt;RPC&lt;/a&gt;, so RCP's port, TCP and UDP port 111, has to be allowed for incoming connections. Use the commands &lt;code&gt;iptables -I INPUT -m state --state NEW -m tcp -p tcp -s &lt;em&gt;X.X.X.X&lt;/em&gt;/24 --dport 111 -j ACCEPT; iptables -I INPUT -m state --state NEW -m udp -p udp -s &lt;em&gt;X.X.X.X&lt;/em&gt;/24 --dport 111 -j ACCEPT;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Gluster's own services – For Gluster to access its bricks on each cluster node, you have to allow TCP ports 24007, 24008, and 24009, plus an additional number of ports in sequence equivalent to the number of bricks across all volumes. Thus if you have two bricks in the cluster, you have to allow ports from 24007 to 24011 (24009 plus 2). The command for this is &lt;code&gt;iptables -A INPUT -m state --state NEW -m tcp -p tcp -s &lt;em&gt;X.X.X.X&lt;/em&gt;/24 --dport 24007:24011 -j ACCEPT&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Other access – Allow other remote connections if you want to use NFS, iSCSI, or other connectivity. You don't have to allow other ports if you plan to mount volumes with the native GlusterFS filesystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The above rules allow all cluster nodes and clients from the &lt;em&gt;X.X.X.X&lt;/em&gt; C-class network to communicate. You can also apply these rules on a per-host basis by using &lt;em&gt;Y.Y.Y.Y&lt;/em&gt; for the IP address of each host instead of &lt;em&gt;X.X.X.X&lt;/em&gt;/24 for the network.&lt;/p&gt;
&lt;p&gt;Don't forget to save the iptables configuration once you've added the new rules by using the command &lt;code&gt;service iptables save&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Prepare disks for Gluster storage&lt;/h3&gt;
&lt;p&gt;To comply with best practices, use one disk for the operating system and dedicate one or more others for Gluster's storage only. Also, format the future Gluster storage disk with the &lt;a href="http://en.wikipedia.org/wiki/XFS"&gt;XFS&lt;/a&gt; filesystem, which is fast, scalable, and reliable for distributed storage.&lt;/p&gt;
&lt;p&gt;So far you've installed Gluster on one disk and have just attached another for Gluster storage. The new disk is not formatted and appears under the name /dev/sdb. You can acknowledge the disk with the command &lt;code&gt;fdisk -l&lt;/code&gt;, which should show the new disk with valid partitions.&lt;/p&gt;
&lt;p&gt;To prepare the disk, first use fdisk to create a primary partition on the new disk. Run the command &lt;code&gt;fdisk /dev/sdb&lt;/code&gt; and select "n" for new partition, "p" for primary, "1" for first. Then write the new partition table to the disk by selecting "w." You should now have a new primary partition under the name /dev/sdb1.&lt;/p&gt;
&lt;p&gt;Next, format the new partition with the XFS filesystem with the command &lt;code&gt;mkfs.xfs /dev/sdb1&lt;/code&gt;. Create a new directory to be used as a mount point for the /dev/sdb1 partition, such as /export/brick1. Brick1 is a good name because this partition will be used for the first brick, which is to say the first exported directory found on the first node.&lt;/p&gt;
&lt;p&gt;Finally, make sure the new partition /export/brick1 is automatically mounted during system boot time by adding a new row to /etc/fstab: &lt;code&gt;/dev/sdb1 /export/brick1 xfs defaults 1 2&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Set trusted storage pools&lt;/h3&gt;
&lt;p&gt;Gluster unites cluster nodes into a trusted pool, and all nodes inside this pool share disk resources and offer storage services. Acting as one logical entity, a trusted pool provides redundancy, better storage performance, and scalability.&lt;/p&gt;
&lt;p&gt;To manage a new trusted pool, and in fact manage all parts of Gluster, use the &lt;a href="http://gluster.org/community/documentation/index.php/Gluster_3.2:_gluster_Command"&gt;Gluster console manager&lt;/a&gt; at &lt;code&gt;/usr/sbin/gluster&lt;/code&gt;. This command-line tool accepts arguments for options; there is no GUI.&lt;/p&gt;
&lt;p&gt;A storage pool is created automatically when you install and start Gluster on the first cluster node. From the first node you can add the rest of the nodes after you install and start Gluster on them.&lt;/p&gt;
&lt;p&gt;For example, suppose you installed Gluster on a node with the IP address 10.1.1.1 and you want to add to the pool a node with IP 10.1.1.2. To accomplish this use the Gluster console manager with the arguments &lt;code&gt;peer probe [&lt;em&gt;host&lt;/em&gt;]&lt;/code&gt;, as in &lt;code&gt;/usr/sbin/gluster peer probe 10.1.1.2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Similarly, you can remove servers from the storage pool with the command &lt;code&gt;/usr/sbin/gluster peer detach [&lt;em&gt;host&lt;/em&gt;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After adding servers to or removing them from the trusted storage pool, you should check the pool's status. Use the command &lt;code&gt;/usr/sbin/gluster peer status&lt;/code&gt; to confirm you have the correct number of peers and their statuses.&lt;/p&gt;
&lt;h3&gt;How to manage Gluster volumes&lt;/h3&gt;
&lt;p&gt;A Gluster volume is a logical entity composed of bricks, which are exported directories from servers inside the trusted pool. One pool can support numerous volumes. You can start managing Gluster volumes as soon as you have a trusted storage pool set up.&lt;/p&gt;
&lt;p&gt;Gluster supports many advanced &lt;a href="http://gluster.org/community/documentation/index.php/Gluster_3.2:_Setting_Volume_Options"&gt;options&lt;/a&gt; for its volumes. For instance, you can create a distributed, striped, and replicated volume. Such a volume performs well, first because it's distributed – reads and writes happen on multiple servers. Second, the fact that it is striped ensures that large files are striped across multiple bricks and servers and thus accessed faster. High availability is ensured by the fact that the volume and its data is replicated and redundant, so if one node fails another covers for it and there is no interruption in service.&lt;/p&gt;
&lt;p&gt;To create a distributed, striped, and replicated volume use the command /usr/sbin/gluster volume create &lt;em&gt;volumename&lt;/em&gt; [stripe &lt;em&gt;count&lt;/em&gt;] [replica &lt;em&gt;count&lt;/em&gt;] &lt;em&gt;host:/brickname&lt;/em&gt;. An example of the command would look like: &lt;code&gt;/usr/sbin/gluster volume create testvolume stripe 2 replica 2 10.1.1.1:/export/brick1 10.1.1.2:/export/brick2&lt;/code&gt;. This creates a volume called "testvolume" striped across two bricks, replicated twice. The volume consists of two nodes and their bricks – 10.1.1.1:/export/brick1 and 10.1.1.2:/export/brick2.&lt;/p&gt;
&lt;p&gt;Once you have a Gluster volume you can easily and seamlessly change its size without interrupting the storage operations. For example, if you want to increase the size of your volume you can add more cluster nodes with more bricks attached to them. First, add each additional node with the command &lt;code&gt;/usr/sbin/gluster peer probe &lt;em&gt;host&lt;/em&gt;&lt;/code&gt;. Then use the command &lt;code&gt;/usr/sbin/gluster volume add-brick &lt;em&gt;volumename&lt;/em&gt; &lt;em&gt;host:/brickname&lt;/em&gt;&lt;/code&gt;. Finally, rebalance and redistribute the volume evenly across all the bricks with the command &lt;code&gt;/usr/sbin/gluster volume rebalance &lt;em&gt;volumename&lt;/em&gt; start&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You need to keep a few concepts in mind for proper volume management and configuration. First, you should use only one brick per server in a given volume so that in case of a crash it can be covered for by its replicating peer. Second, the number of bricks should be a multiple of the replica number – that is, how many times data should be replicated – so that valid replication can be established. For example, if you want data to be replicated twice, you should build your cluster from any number of bricks that's a multiple of two. Last, the number of stripes should be equal to the number of bricks so that you can gain performance by reading from and writing to multiple locations simultaneously.&lt;/p&gt;
&lt;h3&gt;Connect a client to the storage&lt;/h3&gt;
&lt;p&gt;The best way to connect to Gluster storage is through GlusterFS, which allows clients to take advantage of Gluster's clustering and high reliability features. GlusterFS offers better performance and reliability than non-native communication methods such as NFS or iSCSI, and GlusterFS allows clients to communicate simultaneously with multiple cluster nodes.&lt;/p&gt;
&lt;p&gt;GlusterFS is based on &lt;a href="http://fuse.sourceforge.net/"&gt;filesystem in userspace&lt;/a&gt; (FUSE). Prior to installing GlusterFS you have to install the &lt;code&gt;fuse&lt;/code&gt; and &lt;code&gt;fuse-libs&lt;/code&gt; packages. In CentOS these prerequisite packages can be installed through the official repository with the command &lt;code&gt;yum install fuse fuse-libs&lt;/code&gt;. You must run this installation only on the clients from which you will connect to the storage; FUSE is automatically installed with the Gluster server software.&lt;/p&gt;
&lt;p&gt;Restart the server after installing the fuse package in order to load the fuse kernel module, or if you want to postpone the restart you can manually load the module using the command &lt;code&gt;modprobe fuse&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Next, to install GlusterFS, you have to add Gluster's repository just as you added it on the cluster nodes, with the command &lt;code&gt;wget -P /etc/yum.repos.d http://download.gluster.org/pub/gluster/glusterfs/LATEST/EPEL.repo/glusterfs-epel.repo&lt;/code&gt;, and install glusterfs-fuse with the command &lt;code&gt;yum install glusterfs-fuse&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Once you've installed all the necessary software you can mount a GlusterFS volume. You can use the &lt;code&gt;/bin/mount&lt;/code&gt; command with "glusterfs" as parameter for the filesystem (&lt;code&gt;-t&lt;/code&gt; option) and a few other GlusterFS-specific parameters; for example, &lt;code&gt;mount -t glusterfs -o backupvolfile-server=10.1.1.2 10.1.1.1:/testvolume /media/gluster&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This example mounts the volume "testvolume" from the Gluster node 10.1.1.1. The option &lt;code&gt;backupvolfile-server&lt;/code&gt; instructs the client to work with the replicating Gluster node 10.1.1.2 in case 10.1.1.1 fails.&lt;/p&gt;
&lt;p&gt;Once the volume is mounted, Linux treats it just as any other disk resource. Multiple clients can mount the same volume and work with it at the same time.&lt;/p&gt;
&lt;p&gt;Gluster is a powerful distributed storage system that helps meet the growing need for better Linux-native storage. It's easy to implement and work with, limited only by the system resources you can dedicate to it, and doesn't require you to buy any expensive vendor-specific hardware.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/284663/Create-distributed-storage-with-Gluster&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/GIiRoIF3klk" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Thu, 18 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:284663</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/284663/Create-distributed-storage-with-Gluster</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/283711/How-to-set-up-Solr-4-2-on-Drupal-7-with-Apache#Comments</comments><slash:comments>1</slash:comments><title>How to set up Solr 4.2 on Drupal 7 with Apache</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/6nFB33Y4PJA/How-to-set-up-Solr-4-2-on-Drupal-7-with-Apache</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/solr"&gt;Solr&lt;/a&gt; is an open source search server based on &lt;a href="http://olex.openlogic.com/packages/lucene"&gt;Apache Lucene&lt;/a&gt;. Lucene provides Java-based indexing and a search library, and Solr extends it to provide a variety of APIs and search functionality, including faceted search and hit highlighting, and handles Word and PDF document searching. It also provides caching and replication, making it scalable, robust, and very fast.&lt;/p&gt;
&lt;p&gt;Happily, Solr also plays nicely with &lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, the popular CMS platform. If you want fast and effective search on your Drupal site, installing Solr is a straightforward way of getting it quickly. Until this month, the Apachesolr Drupal module didn't support the current Solr 4.x schemas, but as of the very latest version of the Apachesolr module, 7.x-1.2, you can now set up Solr 4.x on your Drupal 7 site. This tutorial assumes that you're running Drupal 7.22 (the most up-to-date version) under &lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt; on a Linux box.&lt;/p&gt;
&lt;h3&gt;Installing Apachesolr&lt;/h3&gt;
&lt;p&gt;You need two components to run Solr with Drupal: the Apachesolr Drupal module, and the Solr server itself. The server runs independently of your Drupal/Apache installation when it indexes the data. The module links that independent Solr server with your Drupal install, passing data into Solr to index, and then enabling Drupal to serve up the search results.&lt;/p&gt;
&lt;p&gt;You need to start by installing the Drupal Apachesolr module, as it has some config options you need to set up the Solr server. You can download the most recent version of the module from the bottom of &lt;a href="http://drupal.org/project/apachesolr"&gt;the Drupal Apachesolr web page&lt;/a&gt;. &lt;em&gt;Important note:&lt;/em&gt; As of the version of 13 April 2013, this module should work with 4.x Solr; older versions only work with 3.x Solr. Unpack the tarball and move the unpacked apachesolr directory to your modules directory, which might be sites/all/modules or /sites/all/contrib, depending on your setup.&lt;/p&gt;
&lt;p&gt;Now log into your Drupal install from the web dashboard as admin, and go to the Modules tab. You may need to manually run the "check for updates" task, but after that, you should see the Apache Solr modules available at the bottom of the modules list. Click the boxes to enable them.&lt;/p&gt;
&lt;h3&gt;Installing Solr&lt;/h3&gt;
&lt;p&gt;Next you'll need to install the Solr server itself. Go to http://www.apache.org/dyn/closer.cgi/lucene/solr/ to find your closest mirror, and download the most recent release (4.2.1 at time of writing). Unpack it somewhere outside your web directory; /opt/solr or /usr/local/solr are good choices.&lt;/p&gt;
&lt;p&gt;The next step is to configure Solr to talk to your Drupal site. There's a decent example Solr setup in /opt/solr-4.2.1/example/. Copy that across to your own Solr directory before you start making changes:&lt;/p&gt;
&lt;pre&gt;cp -rf example/ my-drupal-solr/ cd my-drupal-solr/&lt;/pre&gt;
&lt;p&gt;By default, Solr looks for its configuration in solr/solr.xml. If that file is missing, it assumes the config is kept instead in solr/collection1/. We will put our Drupal config (taken from the Apachesolr Drupal module) in that collection1/ directory, and move aside the solr.xml config:&lt;/p&gt;
&lt;pre&gt; 
cd solr/ 
mv solr.xml solr.bak 
cp /var/www/sites/all/modules/apachesolr/solr-conf/solr-4.x/* collection1/conf/
&lt;/pre&gt;
&lt;p&gt;Now start your Solr server with &lt;code&gt;java -jar start.jar&lt;/code&gt;, and go to http://localhost:8983/solr to check the Solr admin console and make sure that your Solr server is running.&lt;/p&gt;
&lt;h3&gt;Indexing and checking Solr with Drupal, and other setup notes&lt;/h3&gt;
&lt;p&gt;To confirm that Solr is talking to Drupal, and that the indexing is working correctly, go to the Drupal console, and go to Configuration -&amp;gt; Apache Solr search. Here you can submit all pages for indexing, and then run the indexing immediately rather than waiting for the next cron job. It will take a couple of minutes for the indexing to complete. Once it does, go to http://localhost/?q=search/site and enter a term in the search box. You should get a successful search result. If you don't, check that you've got the Apachesolr configuration files in the right place for your Solr install to pick them up, as described in the section above.&lt;/p&gt;
&lt;p&gt;Right now if you try searching using the Content rather than the Node search tab, or from the default Drupal front page search box, you won't get any results. To fix this, go back to the Apache Solr module configuration page and click the Pages/Blocks tab. You'll see Core Search listed, and a Taxonomy Search. Click Clone next to Core Search, then edit the cloned search. Rename it Content, edit the Description and Title fields appropriately, and change the Path field to &lt;code&gt;search/node&lt;/code&gt;. Save this and try the Content search again, and all should work fine.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/solr_pagesblocks-resized-600.png" border="0" alt="solr pagesblocks resized 600"&gt;&lt;/p&gt;
&lt;p&gt;You may also wish to set Apache Solr as the default search from the Search module configuration page.&lt;/p&gt;
&lt;h3&gt;Run Solr automatically&lt;/h3&gt;
&lt;p&gt;At this point you are running Solr manually, which you probably don't want to do on a production site. To get it to start on startup, you need a startup script. Here's a basic one that should do the trick. Save it as /etc/init.d/solr and make it executable by root:&lt;/p&gt;
&lt;pre&gt;#!/bin/sh

# Prerequisites:
# 1. Check SOLR_DIR value is correct
# 2. daemon needs to be installed
# 3. Script needs to be executed by root

# This script will launch Solr in a mode that will automatically respawn if it
# crashes. Output will be sent to $LOG. A pid file will be 
# created in the standard location.

NAME=solr 
SOLR_DIR=http://www.openlogic.com/opt/solr-4.2.1/my-solr-drupal 
COMMAND="java -jar start.jar" 
LOG=http://www.openlogic.com/var/log/solr/solr.log

start () {
    echo -n "Starting solr..."

    # start daemon
    daemon --chdir=$SOLR_DIR --command "$COMMAND" --respawn --output=$LOG --name=$NAME --verbose

    RETVAL=$?
    if [ $RETVAL = 0 ]
    then
        echo "done."
    else
        echo "failed. See error code for more information."
    fi
    return $RETVAL
}

stop () {
    # stop daemon
    echo -n "Stopping $NAME..."

    daemon --stop --name=$NAME  --verbose
    RETVAL=$?

    if [ $RETVAL = 0 ]
    then
        echo "done."
    else
        echo "failed. See error code for more information."
    fi
    return $RETVAL
}


restart () {
    daemon --restart --name=$NAME  --verbose
}


status () {
    # report on the status of the daemon
    daemon --running --verbose --name=$NAME
    return $?
}


case "$1" in
    start)
        start
    ;;
    status)
        status
    ;;
    stop)
        stop
    ;;
    restart)
        restart
    ;;
    *)
        echo $"Usage: $NAME {start|status|stop|restart}"
        exit 3
    ;; esac

exit $RETVAL
&lt;/pre&gt;
&lt;p&gt;You can run it manually with &lt;code&gt;/etc/init.d/solr start&lt;/code&gt; to check that it's working correctly. Once it is, add it to your standard startup scripts with &lt;code&gt;update-rc.d solr defaults&lt;/code&gt; on Ubuntu, or if you're on &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt; or another Red Hat-based distro, add the line&lt;/p&gt;
&lt;pre&gt;# chkconfig: 2345 64 36
&lt;/pre&gt;
&lt;p&gt;to the script (note that it's a comment!), then run &lt;code&gt;chkconfig --add solr&lt;/code&gt;. Now when you reboot, Solr should start automatically.&lt;/p&gt;
&lt;p&gt;This is a very basic Solr setup, but it's enough to get you started. If you want to utilize the full power of Solr you can look into faceted search and filtering, further text analysis configuration, or exciting options like geospatial search.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/283711/How-to-set-up-Solr-4-2-on-Drupal-7-with-Apache&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/6nFB33Y4PJA" height="1" width="1"/&gt;</description><dc:creator>Juliet Kemp</dc:creator><pubDate>Mon, 15 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:283711</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/283711/How-to-set-up-Solr-4-2-on-Drupal-7-with-Apache</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/283625/Caching-web-service-results-can-enhance-Apache-application-performance#Comments</comments><slash:comments>0</slash:comments><title>Caching web service results can enhance Apache application performance</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/oGKzBlliMyE/Caching-web-service-results-can-enhance-Apache-application-performance</link><description>&lt;p&gt;Since in most web services, reads outnumber updates by far, you can enhance the performance of a &lt;a href="http://www.ibm.com/developerworks/webservices/library/ws-restful/"&gt;RESTful&lt;/a&gt; server by implementing a local cache, so repeated requests can be fed with local data and don't actually require more expensive processing. Caches are usually associated with static content such as images or videos that don't change over time, but in this article we'll see how to configure &lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt; to work as a reverse proxy, caching dynamic requests to reduce the load on your server.&lt;/p&gt;
&lt;p&gt;Before we start, you may wonder: Should you ever cache your service results? Won't stale data negatively affect users? The answer depends upon your application. For example, in an online retail website, you might have a service return the top 10 bestsellers over the last few hours; is it really worthwhile to recalculate those results for every request? Caching the information will improve responsiveness for your users, and it's quite likely that sending the same results for a certain period of time won't negatively affect the users. Along the same lines, book recommendations for users could be recalculated only once a day or a week. There's no single, simple answer for every application. You should consider each service call and think about whether caching would detract from the value of the information returned.&lt;/p&gt;
&lt;p&gt;In this article we'll keep working with the services we defined in our previous &lt;a href="http://www.openlogic.com/wazi/bid/215833/Apache-and-RESTful-Web-Services"&gt;Apache and RESTful Web Services&lt;/a&gt; articles, which provide REST access to a world database, with information about countries, their regions, and their cities. As most of this data will almost never change, caching is a good solution.&lt;/p&gt;
&lt;p&gt;To begin, configure Apache to enable caching. You have to enable the &lt;a href="http://httpd.apache.org/docs/current/mod/mod_cache.html"&gt;mod_cache&lt;/a&gt; module, plus at least one storage module; we'll go with &lt;a href="http://httpd.apache.org/docs/current/mod/mod_cache_disk.html"&gt;mod_cache_disk&lt;/a&gt;, which stores the cache data in the filesystem, but check the &lt;a href="http://httpd.apache.org/docs/current/caching.html"&gt;Apache Caching Guide&lt;/a&gt; for more options. You'll also have to set some specific headers so data will be cached, and that requires the &lt;a href="http://httpd.apache.org/docs/current/mod/mod_headers.html"&gt;mod_headers&lt;/a&gt; module. To accomplish these tasks on my openSUSE system, I had to edit the /etc/sysconfig/apache2 file and include the new options for the APACHE_MODULES variable, as in &lt;code&gt;APACHE_MODULES="actions ... rewrite &lt;strong&gt;cache disk_cache headers&lt;/strong&gt;"&lt;/code&gt;. You might have to edit a different file if you use another distribution.&lt;/p&gt;
&lt;p&gt;You must also turn caching on and specify what URLs will get cached and where cached files should be stored. In my case, I edited /etc/apache2/default-server.conf to include the lines:&lt;/p&gt;
&lt;pre&gt;CacheEnable disk /rest_rewrite
CacheEnable disk /rest_alias
CacheRoot   /var/cache/apache2
&lt;/pre&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;What gets cached?&lt;/strong&gt;&lt;br&gt;Section 13 of the HTTP definition (&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html"&gt;RFC 2616&lt;/a&gt;) specifies in detail the conditions that allow content to be cached, and Apache follows those rules. Basically, only GET requests may be cached, because they shouldn't create any server-side effects; our services implementation satisfies this condition. (HEAD requests can also be cached, but we didn't include any in our example.) If GET requests include parameters, the server must provide an expiration time, or the request will be considered non-cacheable. PUT, POST, and DELETE requests, which are expected to produce server changes, won't ever be cached. There are some extra rules – for example, only requests that return HTTP status codes 200, 203, 300, 301, or 410 may be cached. You can see the complete rules in the "What can be cached?" section of the &lt;a href="http://httpd.apache.org/docs/current/caching.html#http-caching"&gt;Apache caching guide&lt;/a&gt;.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Each CacheEnable line specifies a URL path to cache; everything beneath becomes a candidate for caching. In our original example we provided two paths for each service, so I've specified two URLs that should be cached. You must refer to the original URL without considering the effects of URL rewriting. The CacheRoot line specifies the caching directory.&lt;/p&gt;
&lt;p&gt;You must also specify the default expiration time for files, or some requests won't be cached even if it's otherwise possible; see "What gets cached?" You can use the FilesMatch directive to be more selective. I arbitrarily decided that for our example only countries requests would get cached, and would expire 10 seconds afterward. (This is obviously a ridiculously quick expiration time, but very good for impatient article writers who don't want to wait when testing their code.) You must also provide a Cache-Control header. You could provide it through code, but it's better not to modify the services themselves, and instead set all the caching configuration without any code changes, at the Apache level:&lt;/p&gt;
&lt;pre&gt;#
# By default everything expires right now.
# Arbitrarily, only the "countries" service is cached.
#
ExpiresActive  On
ExpiresDefault A0
&amp;lt;FilesMatch "countries"&amp;gt;
&amp;nbsp;&amp;nbsp;ExpiresDefault A10
&amp;nbsp;&amp;nbsp;Header append Cache-Control "public"
&amp;lt;/FilesMatch&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After you make these configuration changes, restart or reload the Apache server to make the changes take effect.&lt;/p&gt;
&lt;h3&gt;Is it working?&lt;/h3&gt;
&lt;p&gt;There are several ways you can see whether services are actually being cached. For instance, you can provide some kind of timestamp in the services results or their HTTP headers, or you can configure Apache to do some extra logging. For the former, I modified the common_setup.php code to send a Pragma header with the &lt;a href="http://php.net/manual/en/function.microtime.php"&gt;microtime(1)&lt;/a&gt; value, the current Unix timestamp including microseconds. (&lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.32"&gt;Pragma headers&lt;/a&gt; are implementation-specific values, which are ignored by applications to which they don't apply, so using this header is safe enough.) All service results will include this data, but it will just be ignored.&lt;/p&gt;
&lt;pre&gt;function sendResponseAndExitIf($condition, $code, $description, $extraHeader=false, $xmlResponse=false) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if ($condition) {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;header("HTTP/1.1 {$code} {$description}");
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;strong&gt;header("Pragma: " . microtime(1));&lt;/strong&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
}
&lt;/pre&gt;
&lt;p&gt;We can test whether caching is working by making a certain request repeatedly, and checking timestamps:&lt;/p&gt;
&lt;pre&gt;fkereki@fkereki-desktop:/srv/www/htdocs/services&amp;gt; wget 'http://127.0.0.1/rest_rewrite/countries/UY' -O /dev/tty --save-headers
--2013-04-09 22:32:00--  http://127.0.0.1/rest_rewrite/countries/UY
Connecting to 127.0.0.1:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1714 (1.7K) [text/xml]
Saving to: `/dev/tty'
HTTP/1.1 200 OK
Date: Wed, 10 Apr 2013 01:32:00 GMT
Server: Apache/2.2.22 (Linux/SUSE)
X-Powered-By: PHP/5.4.13
&lt;strong&gt;Pragma: 1365557520.4992&lt;/strong&gt;
Content-Length: 1714
Cache-Control: max-age=10, public
Expires: Wed, 10 Apr 2013 01:32:10 GMT
Vary: Accept-Encoding
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/xml; charset=UTF-8

&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
&amp;lt;countries&amp;gt;&amp;lt;country&amp;gt;&amp;lt;link rel='Uruguay' href='http://192.168.1.200/rest_rewrite/countries/UY' /&amp;gt;&amp;lt;code&amp;gt;UY&amp;lt;/code&amp;gt;&amp;lt;name&amp;gt;Uruguay&amp;lt;/name&amp;gt;&amp;lt;regions&amp;gt;&amp;lt;link rel='Artigas' href='http://192.168.1.200/rest_rewrite/regions/UY/01' /&amp;gt;
&amp;lt;link rel='Canelones' href='http://192.168.1.200/rest_rewrite/regions/UY/02' /&amp;gt;
&lt;em&gt;...many lines snipped...&lt;/em&gt;
...&amp;lt;link rel='Treinta y Tres' href='http://192.168.1.200/rest_rewrite/regions/UY/19' /&amp;gt;
100%[================================================================================================================================================================&amp;gt;] 1,714       --.-K/s   in 0s      

2013-04-09 22:32:00 (265 MB/s) - `/dev/tty' saved [1714/1714]

&amp;gt; wget 'http://127.0.0.1/rest_rewrite/countries/UY' -O /dev/tty --save-headers
--2013-04-09 22:32:05--  http://127.0.0.1/rest_rewrite/countries/UY
...
&lt;strong&gt;Pragma: 1365557520.4992&lt;/strong&gt;
...
Expires: Wed, 10 Apr 2013 01:32:10 GMT
Age: 5
...

&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
&amp;lt;countries&amp;gt;&amp;lt;country&amp;gt;&amp;lt;link rel='Uruguay' href='http://192.168.1.200/rest_rewrite/countries/UY' /&amp;gt;&amp;lt;code&amp;gt;UY&amp;lt;/code&amp;gt;&amp;lt;name&amp;gt;Uruguay&amp;lt;/name&amp;gt;&amp;lt;regions&amp;gt;
&amp;lt;link rel='Artigas' href='http://192.168.1.200/rest_rewrite/regions/UY/01' /&amp;gt;
&lt;em&gt;...many lines snipped...&lt;/em&gt;
...&amp;lt;link rel='Treinta y Tres' href='http://192.168.1.200/rest_rewrite/regions/UY/19' /&amp;gt;
100%[================================================================================================================================================================&amp;gt;] 1,714       --.-K/s   in 0s      

2013-04-09 22:32:05 (152 MB/s) - `/dev/tty' saved [1714/1714]

&amp;gt; wget 'http://127.0.0.1/rest_rewrite/countries/UY' -O /dev/tty --save-headers
--2013-04-09 22:32:07--  http://127.0.0.1/rest_rewrite/countries/UY
...
&lt;strong&gt;Pragma: 1365557520.4992&lt;/strong&gt;
...
Expires: Wed, 10 Apr 2013 01:32:10 GMT
Age: 6
...

&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
&amp;lt;countries&amp;gt;&amp;lt;country&amp;gt;&amp;lt;link rel='Uruguay' href='http://192.168.1.200/rest_rewrite/countries/UY' /&amp;gt;&amp;lt;code&amp;gt;UY&amp;lt;/code&amp;gt;&amp;lt;name&amp;gt;Uruguay&amp;lt;/name&amp;gt;&amp;lt;regions&amp;gt;
&amp;lt;link rel='Artigas' href='http://192.168.1.200/rest_rewrite/regions/UY/01' /&amp;gt;
&lt;em&gt;...many lines snipped...&lt;/em&gt;
...&amp;lt;link rel='Treinta y Tres' href='http://192.168.1.200/rest_rewrite/regions/UY/19' /&amp;gt;
100%[================================================================================================================================================================&amp;gt;] 1,714       --.-K/s   in 0s      

2013-04-09 22:32:07 (269 MB/s) - `/dev/tty' saved [1714/1714]

&lt;/pre&gt;
&lt;p&gt;As you can see, the actual service code was called the first time, and the two next requests were fulfilled from the cache. In the latter cases the service adds the "Age:" header. After a wait that depends on the &lt;code&gt;Cache-Control: max-age&lt;/code&gt; value the timestamp changes, so we know the PHP code was called again.&lt;/p&gt;
&lt;pre&gt;fkereki@fkereki-desktop:/srv/www/htdocs/services&amp;gt; wget 'http://127.0.0.1/rest_rewrite/countries/UY' -O /dev/tty --save-headers
--2013-04-09 22:37:08--  http://127.0.0.1/rest_rewrite/countries/UY
Connecting to 127.0.0.1:80... connected.
...
&lt;strong&gt;Pragma: 1365557828.7668&lt;/strong&gt;
...
Expires: Wed, 10 Apr 2013 01:37:18 GMT
...

&amp;lt;?xml version='1.0' encoding='UTF-8'?&amp;gt;
&amp;lt;countries&amp;gt;&amp;lt;country&amp;gt;&amp;lt;link rel='Uruguay' href='http://192.168.1.200/rest_rewrite/countries/UY' /&amp;gt;&amp;lt;code&amp;gt;UY&amp;lt;/code&amp;gt;&amp;lt;name&amp;gt;Uruguay&amp;lt;/name&amp;gt;&amp;lt;regions&amp;gt;
&amp;lt;link rel='Artigas' href='http://192.168.1.200/rest_rewrite/regions/UY/01' /&amp;gt;
&lt;em&gt;...many lines snipped...&lt;/em&gt;
...&amp;lt;link rel='Treinta y Tres' href='http://192.168.1.200/rest_rewrite/regions/UY/19' /&amp;gt;
100%[================================================================================================================================================================&amp;gt;] 1,714       --.-K/s   in 0s      

2013-04-09 22:37:08 (237 MB/s) - `/dev/tty' saved [1714/1714]
&lt;/pre&gt;
&lt;h3&gt;Adding logging&lt;/h3&gt;
&lt;p&gt;The method above is useful for a quick spot check, but adding logging is a better approach, because it allows you to more thoroughly evaluate the results of your caching. The &lt;a href="http://httpd.apache.org/docs/current/mod/mod_log_config.html"&gt;mod_log_config&lt;/a&gt; module is usually loaded by default; if it's not, edit the APACHE_MODULES variable as above to include it. By adding a few lines to the server configuration, we can ensure all cache requests are logged:&lt;/p&gt;
&lt;pre&gt;#
# Logging: mod_cache runs before mod_env,
# so on a cache hit CACHE_MISS won't be set
# and a dash will be shown instead.
#
SetEnv     CACHE_MISS      "Miss"
LogFormat  "%h %l %u %t \"%r\" %&amp;gt;s %b %{CACHE_MISS}e" common-cache
CustomLog  /var/log/apache2/cache.log common-cache
&lt;/pre&gt;
&lt;p&gt;The CACHE_MISS variable will be set only if the cache wasn't used; for successful cache lookups it will be shown just as a dash, while unsuccessful ones will show "Miss." You can check the online documentation for a full explanation of the &lt;a href="http://httpd.apache.org/docs/current/mod/mod_log_config.html#formats"&gt;format parameters&lt;/a&gt;. We specify the log file in the CustomLog line. After our tests, the file looks like:&lt;/p&gt;
&lt;pre&gt;...
127.0.0.1 - - [09/Apr/2013:22:32:00 -0300] "GET /rest_rewrite/countries/UY HTTP/1.1" 200 1714 Miss
127.0.0.1 - - [09/Apr/2013:22:32:05 -0300] "GET /rest_rewrite/countries/UY HTTP/1.1" 200 1714 -
127.0.0.1 - - [09/Apr/2013:22:32:07 -0300] "GET /rest_rewrite/countries/UY HTTP/1.1" 200 1714 -
127.0.0.1 - - [09/Apr/2013:22:37:08 -0300] "GET /rest_rewrite/countries/UY HTTP/1.1" 200 1714 Miss
&lt;/pre&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Tricking the cache&lt;/strong&gt;&lt;br&gt;If in some case you absolutely require fully up-to-date data, you can trick the cache into calling the actual service by adding an irrelevant parameter to the request; a timestamp does nicely. For example, if you request the service at &lt;code&gt;http://127.0.0.1/rest_rewrite/countries/UY?irrelevant=20130409231846.1532&lt;/code&gt;, the added parameter won't match any cached data, so the cache will be forced to call the service code. Of course, if you were &lt;em&gt;always&lt;/em&gt; to need the latest information, then you shouldn't be caching that particular service at all!&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The first line shows the original request, which had to be fulfilled by calling the PHP service code. The next two requests were satisfied out of the cache, while the last call, after the expiration time of the cache data, also was considered a miss. You can set logging like this and study it to see how much the cache setup is helping speed up your server.&lt;/p&gt;
&lt;h3&gt;Cleaning up&lt;/h3&gt;
&lt;p&gt;All the configuration we've seen so far is fine, but there's an ugly little problem lurking in the shadows: The cache directory will grow forever until it takes over all of your disk space, because the caching module never deletes anything. You could fix this by simply setting up a cron task that would &lt;code&gt;rm -rf&lt;/code&gt; everything in the cache directory, but there's a cleaner way (pun intended) to do this, with &lt;a href="http://httpd.apache.org/docs/current/programs/htcacheclean.html"&gt;htcacheclean&lt;/a&gt;. By running a command along the lines of &lt;code&gt;htcacheclean -d360 -i -n -t -p/var/cache/apache2 -l10M&lt;/code&gt; (with appropriate permissions) you can clean out old entries from your cache directory and keep it trimmed below a maximum size. The parameters for that command are described below; for more possibilities check the documentation.&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="0"&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Parameter&lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;-d360&lt;/td&gt;
&lt;td&gt;Run in daemon mode, every so many minutes (360 in this case).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-i&lt;/td&gt;
&lt;td&gt;Run in "intelligent" mode, only if there were any cache changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-n&lt;/td&gt;
&lt;td&gt;Be "nice" to other programs; favor other processes, even if it delays cleaning a bit.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-t&lt;/td&gt;
&lt;td&gt;Remove empty directories.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-p&lt;/td&gt;
&lt;td&gt;Specify the path to the cache directory.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-l10M&lt;/td&gt;
&lt;td&gt;Limit the cache size to the given size (10 megabytes in this example).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;By the way, you can &lt;a href="http://httpd.apache.org/docs/current/programs/htcacheclean.html#delete"&gt;clean just a specific URL to nullify (delete) a cached entry&lt;/a&gt; in order to force a refresh if you know you have updated data.&lt;/p&gt;
&lt;p&gt;Adding caching to your server so fresh dynamic content won't be needlessly reevaluated can enhance the performance of your server, so consider this kind of caching for your web services.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/283625/Caching-web-service-results-can-enhance-Apache-application-performance&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/oGKzBlliMyE" height="1" width="1"/&gt;</description><dc:creator>Federico Kereki</dc:creator><pubDate>Thu, 11 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:283625</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/283625/Caching-web-service-results-can-enhance-Apache-application-performance</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/281870/Website-editor-showdown-CKEditor-vs-TinyMCE#Comments</comments><slash:comments>5</slash:comments><title>Website editor showdown: CKEditor vs. TinyMCE</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/AUshR72PnTM/Website-editor-showdown-CKEditor-vs-TinyMCE</link><description>&lt;p&gt;What's the best WYSIWYG editor for your website? &lt;a href="http://olex.openlogic.com/packages/ckeditor"&gt;CKEditor&lt;/a&gt; and &lt;a href="http://olex.openlogic.com/packages/tinymce"&gt;TinyMCE&lt;/a&gt; are two popular JavaScript-powered WYSIWYG editors that make editing text on your web pages simple. CKEditor is a powerful, robust editor, while TinyMCE is more of a lightweight, minimalist option. Which should you use? It comes down to which editor has the most relevant functionality to address your needs. Let's look at what each editor has to offer, and see how well each meets a range of use cases.&lt;/p&gt;
&lt;p&gt;Both CKEditor and TinyMCE are easy to install. Both are available as plugins for most content management systems (CMS), and some applications even bundle support for one or the other. &lt;a href="http://olex.openlogic.com/packages/wordpress"&gt;WordPress&lt;/a&gt; for example, uses TinyMCE as the default editor. If a given application doesn't support one or the other out of the box, you can probably add support through a plugin or extension. If you choose to do that, you should install only one WYSIWYG editor on one application.&lt;/p&gt;
&lt;p&gt;Both editors offer the standard HTML formatting tools, such as bold, italic, underline, lists, and various text alignments. Both provide cross-platform support and properly render text in all the popular web browsers.&lt;/p&gt;
&lt;h3&gt;Individual strengths&lt;/h3&gt;
&lt;p&gt;CKEditor offers extensive spell-checking functions, anchor text linking to other areas of the same page, and the ability to expand the editing area as you fill up the box with text. TinyMCE does not.&lt;/p&gt;
&lt;p&gt;CKEditor offers a text editor control panel in WordPress through the CKEditor WordPress plugin; TinyMCE does not. CKEditor, as both a WordPress plugin and standalone, lets you customize the editor's output by making minor changes to things such as color and formatting in the embedded JavaScript code without editing complex configuration files. Making similar changes with TinyMCE is more complex, requiring you to edit your themes/advanced/skins/ui.css file.&lt;/p&gt;
&lt;p&gt;Another way the two differ is in the way they handle a copied page. I browsed over to the Wazi homepage, pressed Ctrl-A to copy the content, then pasted the copied content into each editor. CKEditor kept most of the images and formatting, but TinyMCE managed to grab only the text, without the images or formatting.&lt;/p&gt;
&lt;p&gt;The two editors offer different levels of user interface control to users without forcing them to work at the code level. Both editors let you change things such as the appearance of the text editor or how it behaves when formatting text, but only CKEditor offers you most of this control within an easy-to-use GUI for WordPress users. By contrast, TinyMCE doesn't offer a GUI control panel to make changes to its settings. To gain access to GUI control panel for TinyMCE, WordPress users need to install a plugin called &lt;a href="http://wordpress.org/extend/plugins/tinymce-advanced/"&gt;TinyMCE Advanced&lt;/a&gt;, which offers a control panel under the WordPress settings where you can add or remove additonal TinyMCE formatting features. In standalone installations, neither CKEditor nor TinyMCE offers any sort of control panel.&lt;/p&gt;
&lt;p&gt;CKEditor offers one enterprise-friendly feature that TinyMCE lacks. With the easy-to-use &lt;a href="http://ckeditor.com/builder"&gt;CKBuilder&lt;/a&gt; tool, you can create a custom-designed CKEditor that you can integrate into your website. You can choose a basic, standard, or full set of toolbar icons, select from more than 100 available &lt;a href="http://ckeditor.com/addons/plugins/all"&gt;plugins&lt;/a&gt;, and specify the language for your editor's interface.&lt;/p&gt;
&lt;p&gt;By contrast, if you want to integrate advanced functionality with plugins for TinyMCE, you will need to code them yourself using &lt;a href="http://www.tinymce.com/wiki.php/Plugins"&gt;this page as a rough guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;One simple task indicates the level of customizability of the two editors. If you want to change the interface color for CKEditor, you would have to replace the &amp;lt;textarea&amp;gt; elements on the page you want to modify with a CKEditor instance and include the desired color of the user interface. For example, you can use the code below to specify the uiColor property for the editor embedded on any given page:&lt;/p&gt;
&lt;pre&gt;&amp;lt;script&amp;gt;

			// Replace the &amp;lt;textarea id="editor"&amp;gt; with an CKEditor
			// instance, using default configurations.
			CKEDITOR.replace( 'editor1', {
				uiColor: '#14B8C4',
				toolbar: [
					[ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],
					[ 'FontSize', 'TextColor', 'BGColor' ]
				]
			});

		&amp;lt;/script&amp;gt;
&lt;/pre&gt;
&lt;p&gt;It's a little easier if you have a WordPress website that uses the CKEditor plugin. You can simply log in to WordPress, browse over to CKEditor -&amp;gt; Basic Settings and make the change using the GUI.&lt;/p&gt;
&lt;p&gt;For a standalone installation of TinyMCE, you change the appearance of the UI by tweaking the stylesheet settings in the TinyMCE/css/content.css file. Edit the file and look for this entry:&lt;/p&gt;
&lt;pre&gt;body {
	background-color: #FFFFFF;
&lt;/pre&gt;
&lt;p&gt;Change &lt;code&gt;#FFFFFF&lt;/code&gt; to another RGB color code, save the file, and your TinyMCE editor's background will reflect the changes to the background you've selected.&lt;/p&gt;
&lt;p&gt;When it comes to support, &lt;a href="http://cksource.com/"&gt;CKSource&lt;/a&gt;, the company that offers CKEditor, supports its own product. TinyMCE partners with a third-party vendor for support. Both CKEditor's and TinyMCE's support options are paid services. TinyMCE's support vendor &lt;a href="http://www.tinymce.com/enterprise/support.php"&gt;provides assistance&lt;/a&gt; after you've filled out a support request, asking them to reach out to you by phone or email. For CKEditor support, you must have a &lt;a href="http://cksource.com/ckeditor/buy"&gt;paid commercial license&lt;/a&gt;, and you can get support by email only through the &lt;a href="http://cksource.com/contact"&gt;CKSource contact page&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Selecting the best rich text editor&lt;/h3&gt;
&lt;p&gt;If you're looking to have control over a custom website environment, then CKEditor is a clearly the better choice. It's powerful out of the box and simple to customize, while remaining easy enough for any novice to use.&lt;/p&gt;
&lt;p&gt;TinyMCE also offers a decent user experience, but it's better suited for developers looking for a minimalist user interface.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/281870/Website-editor-showdown-CKEditor-vs-TinyMCE&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/AUshR72PnTM" height="1" width="1"/&gt;</description><dc:creator>Matt Hartley</dc:creator><pubDate>Mon, 08 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:281870</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/281870/Website-editor-showdown-CKEditor-vs-TinyMCE</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/281586/How-to-write-CentOS-initialization-scripts-with-Upstart#Comments</comments><slash:comments>0</slash:comments><title>How to write CentOS initialization scripts with Upstart</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/qcKmFDO863U/How-to-write-CentOS-initialization-scripts-with-Upstart</link><description>&lt;p&gt;On Linux systems, initialization (init) scripts manage the state of system services during system startup and shutdown. When the system goes through its &lt;a href="http://en.wikipedia.org/wiki/Runlevel"&gt;runlevels&lt;/a&gt;, the &lt;a href="http://en.wikipedia.org/wiki/UNIX_System_V"&gt;System V&lt;/a&gt; init system starts and stops services as configured. While this tried-and-true technology has been around since the dawn of Unix, you can now create modern and efficient &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt; 6 init scripts by using &lt;a href="http://upstart.ubuntu.com/"&gt;Upstart&lt;/a&gt;, an event-based replacement for System V init.&lt;/p&gt;
&lt;p&gt;Until its latest release, CentOS used the System V init system by default. SysV init scripts are simple and reliable, and guarantee a certain order of starting and stopping.&lt;/p&gt;
&lt;p&gt;Starting with version 6, however, CentOS has turned to a new and better init system – Upstart. Upstart is faster than System V init because it starts services simultaneously rather than one by one in a certain order. Upstart is also more flexible and robust, because it is event-based. Upstart generates &lt;a href="http://upstart.ubuntu.com/cookbook/#event"&gt;events&lt;/a&gt; at various times, including while going through the system runlevels, similar to the SysV init system. However, Upstart may also generate custom events. For example, with Upstart you can generate an event that requires certain services to be started, regardless of the runlevel. And Upstart not only generates events, it also handles them – so, for example, when it acknowledges the event for starting a service it will do so. This event-based behavior is robust and fast.&lt;/p&gt;
&lt;p&gt;Upstart supports SysV init scripts for compatibility reasons; most service init scripts in CentOS 6 continue to be SysV-based. You might someday have to create an init script yourself if you write custom software. If you do, you should write your new init scripts with Upstart in mind so you can benefit from the new init system's faster performance and additional features.&lt;/p&gt;
&lt;h3&gt;Beginning the Upstart init script&lt;/h3&gt;
&lt;p&gt;Upstart keeps init scripts in the /etc/init/ directory. A script's name should correspond to the name of the service or job it controls, with a .conf extension. The init script for the Tomcat service, for example, should be named /etc/init/tomcat.conf.&lt;/p&gt;
&lt;p&gt;Like SysV init scripts, Upstart init scripts are regular Bash scripts, but extended with some Upstart-specific directives, which are called stanzas in Upstart. In SysV init scripts you commonly see the line &lt;code&gt;. /etc/init.d/functions&lt;/code&gt;, which provides access to additional necessary SysV functions. Upstart scripts are more sophisticated and complete; you don't have to include any additional functions or libraries.&lt;/p&gt;
&lt;p&gt;Just as in any Bash script, comments in Upstart scripts start with #. Put descriptive comments at the beginning of each script to explain its purpose, and in other places where the code may need explanation. You can use two special stanzas, &lt;code&gt;author&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt;, for documentation.&lt;/p&gt;
&lt;h3&gt;Defining when a service starts&lt;/h3&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 32%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Tasks and services&lt;/strong&gt;&lt;br&gt;Upstart manages two types of jobs: tasks and services. Tasks are short-lived processes that are expected to start, complete a task, then die. One example for such a task job is defined in /etc/init/control-alt-delete.conf in CentOS 6. It restarts the computer when a user presses the Control, Alt, and Delete keys.&lt;/p&gt;
&lt;p&gt;In contrast to a task job, a service job handles a daemon or service, such as the &lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt; web service. This article focuses on service jobs.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;After the introductory comments you can define when a service should start and stop using the special stanzas &lt;code&gt;stop on&lt;/code&gt; and &lt;code&gt;start on&lt;/code&gt;. These two stanzas can be used with a recognized Upstart event such as when the system enters a runlevel.&lt;/p&gt;
&lt;p&gt;Usually administrators configure service jobs to start and stop with the server. By convention, in CentOS you should configure a service job to start at runlevels 2, 3, 4, and 5 and stop at runlevels 0, 1, and 6. In an Upstart init script this is written like this:&lt;/p&gt;
&lt;pre&gt;start on runlevel [2345]
stop on runlevel [06]
&lt;/pre&gt;
&lt;p&gt;This instructs Upstart to start and stop the service whenever the system enters the runlevel in brackets.&lt;/p&gt;
&lt;p&gt;Upstart also lets you start or stop services based on other types of events, such as the starting or stopping of other services. For example, suppose you have an Apache web server integrated with a &lt;a href="http://olex.openlogic.com/packages/varnish"&gt;Varnish&lt;/a&gt; caching web server, as described in the article &lt;a href="http://www.openlogic.com/wazi/bid/266473/Varnish-improves-web-performance-and-security"&gt;Varnish improves web performance and security&lt;/a&gt;. In such a scenario you should make sure that Varnish starts whenever Apache starts, so the configuration stanza for Varnish should look like:&lt;/p&gt;
&lt;pre&gt;start on starting httpd
stop on stopped httpd
&lt;/pre&gt;
&lt;p&gt;The latter stanza is an unique feature of Upstart; Upstart init scripts can stop services at the same time as other services are stopped, while SysV init scripts depend solely on runlevels.&lt;/p&gt;
&lt;p&gt;Another difference is that you configure SysV init scripts when to start and stop by placing symlinks to them in the corresponding runlevels' directories in /etc/rc&lt;em&gt;X&lt;/em&gt;.d/, where &lt;em&gt;X&lt;/em&gt; is the runlevel number. The command &lt;code&gt;chkconfig&lt;/code&gt; does this automatically for you in CentOS. While &lt;code&gt;chkconfig&lt;/code&gt; continues to manage most of the init scripts in CentOS 6, it does not work with Upstart, and you cannot manage Upstart jobs with it.&lt;/p&gt;
&lt;h3&gt;Preparing for an Upstart job&lt;/h3&gt;
&lt;p&gt;To prepare and customize your environment for an Upstart service job you can use a few additional parameters, each on a new line in the job's .conf file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;respawn – When you use this parameter the service process will be restarted if it dies unexpectedly. Without this Upstart parameter you might have to write a dedicated wrapper program to start a service and ensure its proper and constant operation, such as &lt;a href="http://dev.mysql.com/doc/refman/5.6/en/mysqld-safe.html"&gt;mysqld_safe&lt;/a&gt; for starting MySQL.&lt;/li&gt;
&lt;li&gt;expect fork – Every service job should be expected to fork in as a background process. When you specify this parameter Upstart obtains the new process's PID, which it can use later to send signals to it, such as to shut down or reload configuration.&lt;/li&gt;
&lt;li&gt;kill timeout [seconds] – This is the number of seconds before the process may be forcibly killed. You should specify enough time (say, 120 seconds) so that interruption-sensitive services such as MySQL are able to complete any pending operations and shut down safely.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also adjust a few Bash variables in the job's .conf file. For example, you can configure the umask (permissions) with which new files will be created. A secure choice is &lt;code&gt;umask 007&lt;/code&gt;, which means that new files will be created with restrictive permissions 770, which allow only the user itself and the members of its user group to manipulate the newly created files.&lt;/p&gt;
&lt;p&gt;A special Upstart stanza &lt;code&gt;pre-start&lt;/code&gt; allows you to specify a command or inline script to be run right before Upstart actually starts the job. This stanza is suitable for specifying any sanity checks, such the existence of a necessary file. You may also define prerequisite tasks, such as cleaning of the caching directory of a caching proxy. If the &lt;code&gt;pre-start&lt;/code&gt; procedure fails – that is, if it exits with a code other than zero – then the whole job fails and the service is not started.&lt;/p&gt;
&lt;p&gt;To see how this works, here's a pre-start directive to remove PHP accelerator eAccelerator's previously cached files, as you would want to do when eAccelerator is integrated with Apache: &lt;code&gt;pre-start exec rm /var/cache/eaccelerator/* -rf&lt;/code&gt;. A longer example with a whole inline script looks like:&lt;/p&gt;
&lt;pre&gt;pre-start script
    # check if Apache's binary is executable or fail 
    [ -x /usr/sbin/httpd ]
    # clear the /tmp directory from old sessions
    rm /tmp/sess_*
end script
&lt;/pre&gt;
&lt;p&gt;Several other stanzas are similar to the &lt;code&gt;pre-start&lt;/code&gt; stanza:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;post-start&lt;/code&gt; – specifies a procedure to run after starting the service. This is usually useful for complex services that may need additional attention after startup, such as &lt;a href="http://olex.openlogic.com/packages/mysql"&gt;MySQL&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pre-stop&lt;/code&gt; – specifies actions used in preparing for the service shutdown. It is rarely used.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;post-stop&lt;/code&gt; – may be regarded as an alternative to the &lt;code&gt;pre-start&lt;/code&gt; stanza; in some cases it makes more sense to take some actions right after service shutdown instead of waiting for its next start.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Configuring the Upstart start command or script&lt;/h3&gt;
&lt;p&gt;Once you've configured your environment, the last thing you must do is define the job's command or script using the stanzas &lt;code&gt;script ... end script&lt;/code&gt; to write a regular Bash script inline, or just &lt;code&gt;exec&lt;/code&gt; to simply execute a command with arguments. Here's an example that uses the script stanza for the rsyslog service in the rsyslog.conf file:&lt;/p&gt;
&lt;pre&gt;script
    . /etc/default/rsyslog
    exec rsyslogd $SYSLOGD_OPTIONS
end script
&lt;/pre&gt;
&lt;p&gt;The above directive first sources (includes) the content of the file /etc/sysconfig/rsyslog, where the variable SYSLOGD_OPTIONS is defined. This variable is then used to start the rsyslogd service. This is a convenient way to start a service that requires complex or custom configuration, and it's why such &lt;code&gt;script&lt;/code&gt; stanzas are suitable for services such as MySQL or Apache.&lt;/p&gt;
&lt;p&gt;Alternatively, the &lt;code&gt;exec&lt;/code&gt; stanza lets you specify an executable file and any additional arguments it may need. It's suitable for simpler services; for example, you can start the CUPS daemon with the directive &lt;code&gt;exec /usr/sbin/cupsd -F&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;How Upstart stops and reloads services&lt;/h3&gt;
&lt;p&gt;If you're familiar with SysV init scripts, you may wonder how you configure the commands to stop a service or reload its configuration. The answer is that you don't have to; with Upstart you only configure the start command for a service. When Upstart starts a service it keeps track of its PID and the PIDs of the process forks. When Upstart later needs to shut down a service, it does so with the native &lt;a href="http://en.wikipedia.org/wiki/Unix_signal"&gt;Unix signals&lt;/a&gt;. Upstart first sends a PID the SIGTERM signal to gracefully shut it down. If the process ignores SIGTERM, Upstart sends SIGKILL to forcibly kill it. Similarly, when the configuration needs to be reloaded, Upstart sends the SIGHUP signal. Upstart's simple architecture removes the needs to specify procedures for stopping, restarting, and reloading a service, though if the shutdown procedure for a service requires more than just sending SIGHUP or SIGTERM signals, you can use the &lt;code&gt;pre-stop&lt;/code&gt; and &lt;code&gt;post-stop&lt;/code&gt; stanzas.&lt;/p&gt;
&lt;p&gt;One last and important difference between Upstart and SysV inits is how you manually start and stop jobs. Upstart works with the command /sbin/initctl, the init daemon control tool. It accepts as a first argument &lt;code&gt;stop&lt;/code&gt;, &lt;code&gt;start&lt;/code&gt;, &lt;code&gt;restart&lt;/code&gt;, or &lt;code&gt;reload&lt;/code&gt;, and changes the state of the service correspondingly. The second argument is the name of the service. For example, to start MySQL's Upstart job manually you would run the command &lt;code&gt;initctl start mysqld&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I hope you can see the advantages of Upstart's powerful and sophisticated features. Today most default service jobs in CentOS 6 today remain SysV-based, though that will probably change over time. In Ubuntu, for example, Upstart was introduced in 2009, and today most of the init scripts have been migrated to Upstart.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/281586/How-to-write-CentOS-initialization-scripts-with-Upstart&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/qcKmFDO863U" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Thu, 04 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:281586</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/281586/How-to-write-CentOS-initialization-scripts-with-Upstart</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/278127/Write-your-own-Ant-tasks#Comments</comments><slash:comments>0</slash:comments><title>Write your own Ant tasks</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/h2q7Cvu3j2w/Write-your-own-Ant-tasks</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/ant"&gt;Apache Ant&lt;/a&gt; is a Java-based build tool, and because it's based on Java, it is entirely cross-platform. It comes with a huge list of available tasks that you can run simply by including them in a build.xml file, but if there's something you want it &lt;span&gt;to&amp;nbsp;&lt;/span&gt;do and no existing task can do it, it's easy to extend Ant just by writing a new Java class. Here's how to write your very own Ant tasks.&lt;/p&gt;
&lt;p&gt;Before you get started, it's always best to check the &lt;a href="http://ant.apache.org/manual/tasksoverview.html"&gt;list of existing Ant tasks&lt;/a&gt;, and the &lt;a href="http://ant.apache.org/external.html"&gt;list of external (not included in default Ant) tasks&lt;/a&gt; submitted by developers outside the Ant project and not directly supported by the Ant developers. While writing a new task can be fun, there's no need to reinvent the wheel if someone has already done the work for you. If they haven't, because you've found something new it would be handy to do or have unusual specifics you need to manage, you can extend Ant for yourself.&lt;/p&gt;
&lt;h3&gt;A very basic new task&lt;/h3&gt;
&lt;p&gt;To write a new task, you need to extend the Ant Task class. (You can theoretically manage without doing so, but extending Task gives you access to a bunch of useful methods and setup, so it's sensible to use it.) Let's see how with a simple HelloWorld example. Create a new directory hellotask, and a file src/HelloTask.java that contains:&lt;/p&gt;
&lt;pre&gt; 
import org.apache.tools.ant.Task;

public class HelloTask extends Task {
  public void execute() {
    String message = getProject().getProperty("ant.project.name");

    log("Project: " + message);
    log("Hello from " + getLocation());
  }
}
&lt;/pre&gt;
&lt;p&gt;The only method you absolutely must have to extend Task is &lt;code&gt;execute()&lt;/code&gt;. Here, we're calling the logger twice to output two lines. &lt;code&gt;getProject()&lt;/code&gt;, &lt;code&gt;getProperty()&lt;/code&gt;, and &lt;code&gt;getLocation()&lt;/code&gt; are all inherited from the Task class, and do what you'd expect.&lt;/p&gt;
&lt;p&gt;To run and compile this file, obviously we want to use Ant! Here's the build.xml file:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1"?&amp;gt;
&amp;lt;project name="HelloTask" basedir="." default="jar"&amp;gt;

    &amp;lt;property name="src.dir" value="src" /&amp;gt;
    &amp;lt;property name="classes.dir" value="classes" /&amp;gt;

    &amp;lt;target name="clean" description="Delete all generated files"&amp;gt;
        &amp;lt;delete dir="${classes.dir}"/&amp;gt;
        &amp;lt;delete file="${ant.project.name}.jar"/&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name="compile" description="Compile HelloTask"&amp;gt;
        &amp;lt;mkdir dir="${classes.dir}"/&amp;gt;
        &amp;lt;javac srcdir="${src.dir}" destdir="${classes.dir}"/&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name="jar" description="Create JAR" depends="compile"&amp;gt;
        &amp;lt;jar destfile="${ant.project.name}.jar" basedir="${classes.dir}"/&amp;gt;
    &amp;lt;/target&amp;gt;

    &amp;lt;target name="hello" description="Run HelloTask" depends="jar"&amp;gt;
        &amp;lt;taskdef name="hellotask" classname="HelloTask" classpath="${ant.project.name}.jar"/&amp;gt;
        &amp;lt;hellotask /&amp;gt;
    &amp;lt;/target&amp;gt;

&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Most of this should be familiar if you read &lt;a href="http://www.openlogic.com/wazi/bid/271354/Ant-buildfiles-A-look-under-the-carapace"&gt;my tutorial on Ant buildfiles&lt;/a&gt;; it cleans things up, compiles, and creates a JAR from the source code. Run &lt;code&gt;ant jar&lt;/code&gt; to build HelloTask into a JAR.&lt;/p&gt;
&lt;p&gt;The final section is the bit that actually runs the task. The &lt;code&gt;taskdef&lt;/code&gt; (task definition) line tells Ant what to do when it sees &lt;code&gt;&amp;lt;hellotask /&amp;gt;&lt;/code&gt; later on. (With predefined tasks, you don't need this line because Ant already knows how to handle them.) Note that in this setup, where we might be deleting and recompiling the JAR, the &lt;code&gt;taskdef&lt;/code&gt; line must be inside the &lt;code&gt;target&lt;/code&gt; block. If you put the definition earlier in the file, and HelloTask.jar has been deleted (by running &lt;code&gt;ant clean&lt;/code&gt;), Ant won't find the JAR and you'll get an error. Later, if you were to import the JAR elsewhere and just run the task, you could put this line at the top of the file.&lt;/p&gt;
&lt;p&gt;Finally, we set up the &lt;code&gt;hello&lt;/code&gt; target to run &lt;code&gt;&amp;lt;hellotask/&amp;gt;&lt;/code&gt;. Type &lt;code&gt;ant hello&lt;/code&gt; and you should see output a bit like this:&lt;/p&gt;
&lt;pre&gt;Buildfile: /home/juliet/coding/ant/mytask/build.xml

compile:

jar:

hello:
[hellotask] Project: HelloTask
[hellotask] Hello from /home/juliet/coding/ant/mytask/build.xml:24: 

BUILD SUCCESSFUL Total time: 0 seconds
&lt;/pre&gt;
&lt;p&gt;Congratulations – you've created your first task!&lt;/p&gt;
&lt;h3&gt;Handling properties in a task&lt;/h3&gt;
&lt;p&gt;Currently, this task doesn't take parameters. Let's rewrite it so we can pass something in – the name of the task's owner, for example:&lt;/p&gt;
&lt;pre&gt;public class HelloTask extends Task {
    private String owner;

    public void execute() {
        String projectName = getProject().getProperty("ant.project.name");

        log("Project: " + projectName);
        log("Hello to " + owner + " from " + getLocation());
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }
}
&lt;/pre&gt;
&lt;p&gt;Note that the setter method (&lt;code&gt;setOwner()&lt;/code&gt;) must match the name of the variable you wish to set. Ant then generates a matching getter method at compile time, and uses this when the task is run. (You could of course also write your own getter method if you prefer.) Edit build.xml to specify the parameter:&lt;/p&gt;
&lt;pre&gt;&amp;lt;target name="hello" description="Run HelloTask" depends="jar"&amp;gt;
  &amp;lt;taskdef name="hellotask" classname="HelloTask" classpath="${ant.project.name}.jar"/&amp;gt;
  &amp;lt;hellotask owner="Juliet"/&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Run &lt;code&gt;ant hello&lt;/code&gt; and your output should look like this:&lt;/p&gt;
&lt;pre&gt; 
Buildfile: /home/juliet/coding/ant/mytask/build.xml

compile:
    [javac] Compiling 1 source file to /home/juliet/coding/ant/mytask/classes

jar:
      [jar] Building jar: /home/juliet/coding/ant/mytask/HelloTask.jar

hello:
[hellotask] Project: HelloTask
[hellotask] Hello to Juliet from /home/juliet/coding/ant/mytask/build.xml:24: 

BUILD SUCCESSFUL Total time: 0 seconds
&lt;/pre&gt;
&lt;h3&gt;A more complicated task&lt;/h3&gt;
&lt;p&gt;Finally, let's take a look at a more complicated real-world example – an Ant task I wrote to deal with LaTeX files. This is the first, ultra-basic version, which just generates DVI output from a given LaTeX input file. Save this as src/MakeLatex.java:&lt;/p&gt;
&lt;pre&gt;public class MakeLatex extends Task {
  private String input;

  public void execute() {
    log("Building file: " + input);
    String runLatex = "latex " + input;
    try {
      String line;
      Process p = Runtime.getRuntime().exec(runLatex);
      BufferedReader input = new BufferedReader(
          new InputStreamReader(p.getInputStream()));
      while ((line = input.readLine()) != null) {
        System.out.println(line);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void setInput(String input) {
    this.input = input;
  }
}
&lt;/pre&gt;
&lt;p&gt;The setter method is familiar. In &lt;code&gt;execute()&lt;/code&gt;, we send a log message, then create the command to run from the input provided. This command is then run externally with &lt;code&gt;Runtime.getRuntime().exec()&lt;/code&gt;, and the output collected and printed to screen with a &lt;code&gt;BufferedReader&lt;/code&gt; and the &lt;code&gt;while&lt;/code&gt; loop.&lt;/p&gt;
&lt;p&gt;To run this, edit the build.xml file to include this new target:&lt;/p&gt;
&lt;pre&gt;&amp;lt;target name="latex" description="Compile LaTeX" depends="jar"&amp;gt;
    &amp;lt;taskdef name="makelatex" classname="MakeLatex" classpath="${ant.project.name}.jar"/&amp;gt;
    &amp;lt;makelatex input="test"/&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The existing &lt;code&gt;jar&lt;/code&gt; target builds the new class into the HelloTask.jar file. Obviously if you were using this for real you'd want to build it into its own jarfile and save it somewhere else so you could use it in future.&lt;/p&gt;
&lt;p&gt;You also need a test .tex file. (Note: The test file is saved as test.tex, but you don't need the .tex extension when setting &lt;code&gt;input&lt;/code&gt; in build.xml; LaTeX will assume it.):&lt;/p&gt;
&lt;pre&gt;\documentclass[a4paper]{article}
\begin{document} Test!
\end{document}
&lt;/pre&gt;
&lt;p&gt;Run &lt;code&gt;ant latex&lt;/code&gt; to build your file, then look at test.dvi in your preferred DVI viewer to see the output.&lt;/p&gt;
&lt;p&gt;While this approach generates a test.dvi file, it doesn't open it for the user to look at, and it generates a lot of output noise. Also, these days most people prefer PDF output to DVI output – I certainly do! So here's an improved version, which takes an output and a verbosity value:&lt;/p&gt;
&lt;pre&gt; 
public class MakeLatex extends Task {
  private String input;
  private String output = "pdf";
  private Boolean verbose = false;
  private String latexCommand;
  private String showOutputCommand;

  public void execute() {
    log("Building file: " + input);
    if (output.equals("pdf")) {
      latexCommand = "pdflatex";
      showOutputCommand = "xpdf " + input + ".pdf";
    } else if (output.equals("pdf")) {
      latexCommand = "latex";
      showOutputCommand = "xdvi " + input + ".dvi";
    } else {
      log("Don't know how to handle output " + output + "!");
      log("Generating and showing you the dvi instead");
      latexCommand = "latex";
      showOutputCommand = "xdvi " + input + ".dvi";
    }
    String runLatex = latexCommand + " " + input;
    try {
      String line;
      Process p = Runtime.getRuntime().exec(runLatex);
      if (verbose) {
        BufferedReader input = new BufferedReader(
            new InputStreamReader(p.getInputStream()));
        while ((line = input.readLine()) != null) {
          System.out.println(line);
        }
      }
      p = Runtime.getRuntime().exec(showOutputCommand);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public void setInput(String input) {
    this.input = input;
  }
  public void setOutput(String output) {
    this.output = output;
  }
  public void setVerbose(Boolean verbose) {
    this.verbose = verbose;
  }
}
&lt;/pre&gt;
&lt;p&gt;And here's the accompanying buildfile, which specifies the output format and verbosity. If your buildfile doesn't specify output or verbosity values, the task defaults to PDF and to non-verbose:&lt;/p&gt;
&lt;pre&gt;&amp;lt;target name="latex" description="Compile Latex" depends="jar"&amp;gt;
   &amp;lt;taskdef name="makelatex" classname="MakeLatex" classpath="${ant.project.name}.jar"/&amp;gt;
   &amp;lt;makelatex input="test" output="dvi" verbose="true"/&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Ant will now generate the sort of output you prefer, and fire up the specified viewer.&lt;/p&gt;
&lt;p&gt;Finally, one last improvement: Let's pass in a filename from the command line. Ant can do this if you add this code to build.xml:&lt;/p&gt;
&lt;pre&gt;&amp;lt;condition property="params.set"&amp;gt;
  &amp;lt;isset property="input"/&amp;gt;
&amp;lt;/condition&amp;gt;

&amp;lt;target name="latex" description="Compile Latex" depends="jar"&amp;gt;
  &amp;lt;fail unless="params.set"&amp;gt;
     Must specify input file
  &amp;lt;/fail&amp;gt;
  &amp;lt;taskdef name="makelatex" classname="MakeLatex" classpath="${ant.project.name}.jar"/&amp;gt;
  &amp;lt;makelatex input="${input}" verbose="false"/&amp;gt;
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This sets a &lt;code&gt;condition&lt;/code&gt; property, &lt;code&gt;params.set&lt;/code&gt;, based on whether the "input" value is set. When we build the &lt;code&gt;latex&lt;/code&gt; target, Ant first checks the status of &lt;code&gt;params.set&lt;/code&gt;, and fails the build (stopping there) unless it is true. If it is true, the value is passed into the task, and off we go. You call this like so (note the &lt;code&gt;-D&lt;/code&gt; argument):&lt;/p&gt;
&lt;pre&gt; ant latex -Dinput='test'&lt;/pre&gt;
&lt;p&gt;As it stands, this task is very basic. You could add more options to it; for example, you could add other output formats, or a bibtex option. You could also do some error-checking on the input filename; currently if you set input as test.tex rather than test, the task would fail. Experiment a little with the code to see what else you can do with it, and to get a better grasp of writing a task to do exactly what you want it to.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/278127/Write-your-own-Ant-tasks&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/h2q7Cvu3j2w" height="1" width="1"/&gt;</description><dc:creator>Juliet Kemp</dc:creator><pubDate>Mon, 01 Apr 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:278127</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/278127/Write-your-own-Ant-tasks</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/277439/How-to-convert-Apache-rewrites-for-nginx#Comments</comments><slash:comments>4</slash:comments><title>How to convert Apache rewrites for nginx</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/a5_K9rpQrBA/How-to-convert-Apache-rewrites-for-nginx</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt; is still by far the most widely deployed HTTP server, according to &lt;a href="http://news.netcraft.com/archives/category/web-server-survey/"&gt;the latest Netcraft web server survey&lt;/a&gt;, but &lt;a href="http://olex.openlogic.com/packages/nginx"&gt;nginx&lt;/a&gt; has been slowly, steadily gaining market share, thanks to its blazing speed. If you want to try a faster web server and move from Apache to nginx, you'll probably have to change some of your websites' configurations, starting with rewrite directives. To migrate rewrite rules from Apache to nginx, start with these tips and tricks.&lt;/p&gt;
&lt;p&gt;The Apache mod_rewrite module provides powerful and sophisticated tools for nearly all types of URL rewriting. It is, however, somewhat complex, and may be intimidating to beginners. In fact, however, rewrite rules are not magical incantations, though to understand them you need some understanding of regular expressions.&lt;/p&gt;
&lt;p&gt;Even if you have never heard of mod_rewrite, you may still be using it. Popular applications such as &lt;a href="http://olex.openlogic.com/packages/wordpress"&gt;WordPress&lt;/a&gt;, &lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, and Magento are shipped with .htaccess files that contain standard configurations that make these applications work properly, and these usually include one or more rewrites, so to properly move your website to an nginx web server you have to "translate" the Apache mod_rewrite directives into equivalent rules for nginx's HttpRewriteModule.&lt;/p&gt;
&lt;p&gt;If you want to see whether your website is using mod_rewrite, you can use &lt;a href="http://christian.roy.name/blog/detecting-modrewrite-using-php"&gt;this approach&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;In your document root, the directory where you have all your HTML files, add a file named .htaccess, or modify it if it already exists, and make sure it contains these lines:&lt;/p&gt;
&lt;pre&gt;&amp;lt;IfModule mod_rewrite.c&amp;gt;
    // Tell PHP that the mod_rewrite module is ENABLED.
    SetEnv HTTP_MOD_REWRITE On
&amp;lt;/IfModule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then add a second file in your document root named check_rewrite.php with the following content:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?php

if (is_mod_rewrite_enabled()) {
  print "The apache module mod_rewrite is enabled.&lt;br&gt;\n";
} else {
  print "The apache module mod_rewrite is NOT enabled.&lt;br&gt;\n";
}

/**
 * Verifies if the mod_rewrite module is enabled
 *
 * @return boolean True if the module is enabled.
 */
function is_mod_rewrite_enabled() {
  if ($_SERVER['HTTP_MOD_REWRITE'] == 'On') {
    return TRUE;
  } else {
    return FALSE;
  }
}
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now browse to http://yourservername.com/check_rewrite.php, and you can see whether mod_rewrite is enabled.&lt;/p&gt;
&lt;p&gt;As general guide you can follow these simply steps to move your rules from Apache to nginx configuration file:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace the word "RewriteRule" in your Apache configuration files (or .htaccess) with "rewrite"&lt;/li&gt;
&lt;li&gt;Replace the character "^" with "^/"&lt;/li&gt;
&lt;li&gt;Replace the options [L] or [QSA,L] with "last;" (every line in nginx configuration files must end with ";")&lt;/li&gt;
&lt;li&gt;If a rule contains braces – that is, { or } – you have to surround the regular expression with quotation marks.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let's take a look at some examples. Bear in mind that in Apache directives can be written in a .htaccess file in your document root or in the virtual host file configuration. Usually they are located in /etc/apache2/sites-enabled (if you're running Debian or Ubuntu) or /etc/httpd/conf.d/ (under CentOS or Red Hat). In nginx, however, all the configurations regarding a virtual host, including the rewrite rules, are located in its server section, which is usually /etc/nginx/sites-enabled (Debian/Ubuntu) or /etc/nginx/conf.d/ (CentOS, Red Hat).&lt;/p&gt;
&lt;h3&gt;Rewrite rule to change a domain&lt;/h3&gt;
&lt;p&gt;Sometimes you want to rewrite a URL adding (or removing) "www." This might happen if you first published your website without www and later want to change the main URL, but you don't want to lose all the links that are coming from search engines and other websites. So, for example, you could rewrite all the URLs that arrive at linuxaria.com to www.linuxaria.com. In Apache mod_rewrite you would use something similar to these directives:&lt;/p&gt;
&lt;pre&gt;&amp;lt;Virtualhost&amp;gt;
Servername www.linuxaria.com
ServerAlias linuxaria.com
RewriteCond  %{HTTP_HOST}  linuxaria.com
RewriteRule  (.*)          http://www.linuxaria.com$1
...
&lt;/pre&gt;
&lt;p&gt;The easiest way to achieve the same result with nginx is to create two server sections for your virtualhost. In the one for the domain that you want to redirect, include just a rewrite directive, and in the one for the real website, put all the directives you need for your website. So, for the first server, the one you want to redirect, use:&lt;/p&gt;
&lt;pre&gt;server {
    listen       80;
    server_name  linuxaria.com;
    return       301 http://www.linuxaria.com$request_uri;
}
&lt;/pre&gt;
&lt;p&gt;And for the second server, the real website:&lt;/p&gt;
&lt;pre&gt;server {
    listen       80;
    server_name  www.linuxaria.com;
    ...
}
&lt;/pre&gt;
&lt;p&gt;In this example we have not translated the rewrite rules, but rather changed our approach to solve the problem. We'll use the same principle in the next example.&lt;/p&gt;
&lt;h3&gt;WordPress permalinks&lt;/h3&gt;
&lt;p&gt;WordPress permalinks are permanent URLs that link to individual blog posts or categories and other lists of blog postings. Other people can use permalinks to link to your articles, or you might use one to send a link to someone in an email message. To produce "pretty" permalinks, WordPress uses mod_rewrite in Apache, and you should put the following standard rules in your .htaccess file if you use Apache (WordPress will not do this automatically):&lt;/p&gt;
&lt;pre&gt;RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&lt;/pre&gt;
&lt;p&gt;You could translate these statements to "If the requested file is not a real file (!-f) or a directory (!-d), then use the page index.php."&lt;/p&gt;
&lt;p&gt;A "literal" translation of these rules for nginx could be:&lt;/p&gt;
&lt;pre&gt;if (!-f $request_filename){
set $rule_1 1$rule_1;
}
if (!-d $request_filename){
set $rule_1 2$rule_1;
}
if ($rule_1 = "21"){
rewrite /. /index.php last;
}
&lt;/pre&gt;
&lt;p&gt;But this is not an efficient solution with nginx. It's better to change the logic:&lt;/p&gt;
&lt;pre&gt;if (!-e $request_filename)
    {
        rewrite ^(.+)$ /index.php?q=$1 last;
    }
&lt;/pre&gt;
&lt;p&gt;Here the logic says, "If the requested file doesn't exist (!-e) then use the page index.php." This change allow us to get the same result with fewer lines in the configuration file, because Apache mod_rewrite doesn't have this option, but nginx HttpRewriteModule does.&lt;/p&gt;
&lt;h3&gt;Modify a URL extension with nginx&lt;/h3&gt;
&lt;p&gt;Suppose you want to add by default a .html extension to all the URLs of your website, so http://linuxaria.com/myurl would become http://linuxaria.com/myurl.html. This could become necessary if you changed your blog platform, moving from WordPess to Jekyll or another static CMS. In Apache you can get the result with these rules:&lt;/p&gt;
&lt;pre&gt;RewriteCond %{REQUEST_URI} !^.*\.html$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L,R=301]
&lt;/pre&gt;
&lt;p&gt;The nginx approach is similar to the one that we saw above. First we verify that the URL doesn't already contains .html. Next we verify that the requested filename with the extension .html exists. If it does, we rewrite the URL, adding .html to the end:&lt;/p&gt;
&lt;pre&gt;location / {
        # break if URI has .html extension
        if ($request_filename ~* ^.+.html$) {
          break;
        }
        # add .html to URI and serve file, directory, or symlink if it exists
        if (-e $request_filename.html) {
          rewrite ^/(.*)$ /$1.html last;
          break;
        }
      }
&lt;/pre&gt;
&lt;h3&gt;Useful resources&lt;/h3&gt;
&lt;p&gt;To learn more about rewrite rules in nginx, read the &lt;a href="http://wiki.nginx.org/HttpRewriteModule"&gt;Nginx HttpRewriteModule documentation page&lt;/a&gt;, which provides examples and conditions that you can use in your expressions.&lt;/p&gt;
&lt;p&gt;You can also visit two websites that attempt to translate your existing rules for you, though they are not always 100 percent accurate. The &lt;a href="http://winginx.com/htaccess"&gt;htaccess to nginx converter&lt;/a&gt; was conceived as a mod_rewrite-to-nginx converter, but it also allows you to convert some other instructions that you might have reason to port from Apache to nginx. A second script to &lt;a href="http://www.anilcetin.com/convert-apache-htaccess-to-nginx/"&gt;convert Apache htaccess to nginx&lt;/a&gt; is much more "literal" in its translation, but can be useful sometimes.&lt;/p&gt;
&lt;p&gt;This is just a brief introduction to some common rewrite tasks that you might use on your site and that you'll probably need to consider when migrating from Apache to nginx. Rewrites are powerful, and can be complex, but learning how to use rewrites effectively can save your day, and add functionality to your website without the use of other software.&lt;/p&gt;
&lt;p&gt;&lt;span class="hs-cta-wrapper" id="hs-cta-wrapper-204e2db6-1cd0-462a-83b1-51939e2e62ee"&gt;
    &lt;span class="hs-cta-node hs-cta-204e2db6-1cd0-462a-83b1-51939e2e62ee" id="hs-cta-204e2db6-1cd0-462a-83b1-51939e2e62ee"&gt;
        &lt;a href="http://cta-redirect.hubspot.com/cta/redirect/172122/204e2db6-1cd0-462a-83b1-51939e2e62ee" \=""&gt;&lt;img class="hs-cta-img" id="hs-cta-img-204e2db6-1cd0-462a-83b1-51939e2e62ee" style="border-width:0px;" src="http://no-cache.hubspot.com/cta/default/172122/204e2db6-1cd0-462a-83b1-51939e2e62ee.png"&gt;&lt;/a&gt;
    &lt;/span&gt;
    &lt;script type="text/javascript"&gt;
        (function(){
            var s='hubspotutk',r,c=((r=new RegExp('(^|; )'+s+'=([^;]*)').exec(document.cookie))?r[2]:''),w=window;w[s]=w[s]||c,
                hsjs=document.createElement("script"),el=document.getElementById("hs-cta-204e2db6-1cd0-462a-83b1-51939e2e62ee");
            hsjs.type = "text/javascript";hsjs.async = true;
            hsjs.src = "//cta-service-cms2.hubspot.com/cs/loader.js?pg=204e2db6-1cd0-462a-83b1-51939e2e62ee&amp;pid=172122&amp;hsutk=" + encodeURIComponent(c);
            (document.getElementsByTagName("head")[0]||document.getElementsByTagName("body")[0]).appendChild(hsjs);
            try{el.style.visibility="hidden";}catch(err){}
            setTimeout(function() {try{el.style.visibility="visible";}catch(err){}}, 2500);
        })();
    &lt;/script&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/277439/How-to-convert-Apache-rewrites-for-nginx&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/a5_K9rpQrBA" height="1" width="1"/&gt;</description><dc:creator>Riccardo Capecchi</dc:creator><pubDate>Thu, 28 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:277439</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/277439/How-to-convert-Apache-rewrites-for-nginx</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/277036/Three-ways-to-integrate-Tomcat-and-Apache-for-best-performance-and-features#Comments</comments><slash:comments>0</slash:comments><title>Three ways to integrate Tomcat and Apache for best performance and features</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/MaHSQWpQKso/Three-ways-to-integrate-Tomcat-and-Apache-for-best-performance-and-features</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/tomcat"&gt;Tomcat&lt;/a&gt;, the most popular open source implementation of the Java Servlet and JavaServer Pages specifications, is frequently integrated with &lt;a href="http://olex.openlogic.com/packages/apache"&gt;Apache&lt;/a&gt;, the most popular open source web server. Here's a tutorial that shows you three ways to use Tomcat and Apache together.&lt;/p&gt;
&lt;p&gt;For this article I installed Tomcat and Apache on &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt; 6, but the information here should apply to other Linux distributions too. I'm assuming you already have a basic setup of Apache on Linux; if not, on CentOS run the command &lt;code&gt;yum install httpd&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Pros and cons for integrating Tomcat with Apache&lt;/h3&gt;
&lt;p&gt;Tomcat can serve clients perfectly fine by itself, but by integrating it with Apache you get:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Faster static content delivery – Apache serves static content better than Tomcat and supports better caching mechanisms.&lt;/li&gt;
&lt;li&gt;High availability – Apache allows load balancing and clustering of multiple Tomcat servers behind it, thus providing high availability.&lt;/li&gt;
&lt;li&gt;Better security – Apache protects Tomcat through its built-in security features and through advanced third-party modules such as &lt;a href="http://olex.openlogic.com/packages/modsecurity"&gt;ModSecurity&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Extensibility – Apache provides an abundance of modules for just about anything from URL rewriting (ModRewrite) to GeoIP services. With Apache you can use these modules to extend Tomcat's functionality.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Still, there are a few drawbacks for using Tomcat with Apache. First, dynamic content is delivered a little bit more slowly because data has to pass through Apache instead of flowing directly between the client and Tomcat. Second, you have to support an additional service (Apache), thus increasing the complexity of the setup and the maintenance burden.&lt;/p&gt;
&lt;p&gt;Obviously the pros outnumber the cons, and that's why Tomcat is usually integrated with Apache or another web server.&lt;/p&gt;
&lt;h3&gt;Proper Java setup&lt;/h3&gt;
&lt;p&gt;Before you start working with Tomcat and Apache, you should be sure Java is set up properly. By default on most Linux distributions, OpenJDK (the open source Java Development Kit) is installed and supported through the official packet manager. To check if this is the case on your system run &lt;code&gt;java -version&lt;/code&gt; and look for output like:&lt;/p&gt;
&lt;pre&gt;java version "1.7.0_09-icedtea"
OpenJDK Runtime Environment (rhel-2.3.8.0.el6_4-x86_64)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
&lt;/pre&gt;
&lt;p&gt;OpenJDK is fine in most cases since it shares most of the code base with Oracle's commercial JDK. However, for better compatibility and trouble-free Java support you can use Oracle's JDK. To do so, download the latest JDK from &lt;a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html"&gt;Oracle's site&lt;/a&gt;. For CentOS look for the package jdk-7u17-linux-x64.rpm (64-bit architecture) or jdk-7u17-linux-i586.rpm (32-bit architecture). Once you download the installation package, use the command &lt;code&gt;rpm -ivh&lt;/code&gt; to install it.&lt;/p&gt;
&lt;p&gt;If you had OpenJDK installed before you installed Oracle's version you should make sure that Oracle's JDK is the default Java environment. Use the command &lt;code&gt;/usr/sbin/alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 200000&lt;/code&gt; to specify that Oracle's Java binary (/usr/java/latest/jre/bin/java) should be with the highest priority (200000) compared to OpenJDK (by default it has priority 170009).&lt;/p&gt;
&lt;p&gt;You can also use the command &lt;code&gt;alternatives --config java&lt;/code&gt; to change the default Java environment. This command lists all alternatives for Java; choose /usr/java/latest/jre/bin/java as the default one.&lt;/p&gt;
&lt;p&gt;Confirm you have the correct Java by running &lt;code&gt;java -version&lt;/code&gt; again. You should see output like:&lt;/p&gt;
&lt;pre&gt;java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
&lt;/pre&gt;
&lt;h3&gt;Tomcat installation&lt;/h3&gt;
&lt;p&gt;Tomcat 7, the current version, provides the latest features and performance enhancements. In most cases this version should be your choice, but to confirm it suits your business requirements check &lt;a href="http://tomcat.apache.org/whichversion.html"&gt;Tomcat's version comparison page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Usually Tomcat 7 has to be installed from source because most Linux distributions (including CentOS 6) support the previous stable version, Tomcat 6, through their official package managers. To install Tomcat 7 first create a user and group for running the Tomcat service with the commands&lt;/p&gt;
&lt;pre&gt;groupadd tomcat
useradd&amp;nbsp;-s&amp;nbsp;/sbin/nologin&amp;nbsp;-g&amp;nbsp;tomcat&amp;nbsp;tomcat
&lt;/pre&gt;
&lt;p&gt;The first command creates the tomcat group; the second creates the user tomcat as part of the tomcat group, and for security reasons does not allow it to log in to the system.&lt;/p&gt;
&lt;p&gt;After that, download the latest Tomcat installation files from the official &lt;a href="http://tomcat.apache.org/download-70.cgi"&gt;download page&lt;/a&gt;. Extract the files to /usr/share with the command &lt;code&gt;tar zxvf apache-tomcat-7.0.37.tar.gz -C /usr/share/&lt;/code&gt;. Change the ownership of the newly extracted files to the tomcat user and group with the command &lt;code&gt;chown tomcat: /usr/share/apache-tomcat-7.0.37/ -R&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now you can create the startup script for Tomcat 7 in /etc/init.d/tomcat7:&lt;/p&gt;
&lt;pre&gt;#!/bin/bash
# description: Tomcat Start Stop Restart
# processname: tomcat
# chkconfig: 234 20 80
CATALINA_HOME=http://www.openlogic.com/usr/share/apache-tomcat-7.0.37/bin

case $1 in
start)
/bin/su -s /bin/sh tomcat $CATALINA_HOME/startup.sh
;;
stop)
/bin/su -s /bin/sh tomcat $CATALINA_HOME/shutdown.sh
;;
restart)
/bin/su -s /bin/sh tomcat $CATALINA_HOME/shutdown.sh
/bin/su -s /bin/sh tomcat $CATALINA_HOME/startup.sh
;;
esac
exit 0
&lt;/pre&gt;
&lt;p&gt;The above Bash script first sets the home directory for Catalina, Tomcat's servlet container, to /usr/share/apache-tomcat-7.0.37/bin. Then the script defines three scenarios (cases). Depending on the first argument passed to the script (start, stop, or restart) the script runs the corresponding Tomcat start and stop scripts under the tomcat user.&lt;/p&gt;
&lt;p&gt;Make the script executable by changing its permissions to 755 with the command &lt;code&gt;chmod 755 /etc/init.d/tomcat7&lt;/code&gt;. After that you can start Tomcat 7 for the first time with the command &lt;code&gt;service tomcat7 start&lt;/code&gt;. You should also make sure Tomcat starts and stops with the system by running &lt;code&gt;chkconfig tomcat7 on&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To confirm Tomcat 7 has been properly installed and started try to access it at its server's address and TCP port 8080 – for example, http://192.168.1.66:8080. You should see the default Tomcat 7 page.&lt;/p&gt;
&lt;h3&gt;Integrating Tomcat with Apache through ModProxy and ModProxyAJP&lt;/h3&gt;
&lt;p&gt;There are a few ways to integrate Apache with Tomcat, all involving Apache modules that allow Apache to act as an intermediary. The simplest approach is to use &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html"&gt;ModProxy&lt;/a&gt; or &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html"&gt;ModProxyAJP&lt;/a&gt;. The difference between them is mainly in the protocol the modules use to communicate with Tomcat. ModProxy is more transparent and works only with the HTTP protocol, while ModProxyAJP uses Apache JServ Protocol version 1.3 (&lt;a href="http://tomcat.apache.org/connectors-doc-archive/jk2/common/AJPv13.html"&gt;AJP13)&lt;/a&gt;, a binary communication protocol designed to enhance performance.&lt;/p&gt;
&lt;p&gt;Both ModProxy and ModProxyAJP are installed and enabled by default with the httpd package on CentOS. Configuring them is relatively simple; here are two examples. First, to use ModProxy to forward all the requests through Apache to Tomcat, use the directives &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypass"&gt;ProxyPass&lt;/a&gt; and &lt;a href="http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypassreverse"&gt;ProxyPassReverse&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
&lt;/pre&gt;
&lt;p&gt;In CentOS, Apache automatically includes any file with the extension .conf inside the directory /etc/httpd/conf.d/, so place the above lines in a file such as tomcat.conf inside this directory. These two directives tell Apache to provide the necessary proxy functionality to and from Tomcat. Any URL request is forwarded to Tomcat, as configured by the argument / for root directory after the ProxyPass and ProxyPassReverse directives. Here Apache and Tomcat are on the same server, as requests are proxied to localhost at the default Tomcat port 8080.&lt;/p&gt;
&lt;p&gt;Besides listening for http requests on port 8080, Tomcat also listens for the AJP13 protocol on port 8009 by default. To configure Apache to communicate with Tomcat over the AJP13 protocol and port 8009, edit the file /etc/httpd/conf.d/tomcat.conf to look like this:&lt;/p&gt;
&lt;pre&gt;ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
&lt;/pre&gt;
&lt;p&gt;This proxy configuration is almost identical to the previous one, with adjustments only for the protocol (AJP13) and the port (8009). After the adjustments the address of the destination server becomes ajp://localhost:8009/&lt;/p&gt;
&lt;p&gt;To see the difference between the performance of AJP13 and HTTP, try a few tests with the &lt;a href="http://httpd.apache.org/docs/2.2/programs/ab.html"&gt;Apache Benchmark&lt;/a&gt; tool (ab). Ab is part of the CentOS package httpd-tools; you can install it with &lt;code&gt;yum install httpd-tools&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When designing your benchmark tests, make sure you run enough iterations to make your data representative. You should have enough if you send 100,000 requests, 50 concurrent at a time. For target URL you can use one of Tomcat's example Java server pages. You can run such a test with the command &lt;code&gt;/usr/bin/ab -n 100000 -c 50 http://192.168.1.66/examples/jsp/jsp2/el/basic-comparisons.jsp&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Try this command with the two alternative proxy configurations and compare the results. On the average, your results should be 20 percent faster with AJP13 (ModProxyAJP) than with http (ModProxy).&lt;/p&gt;
&lt;h3&gt;Advanced integration of Tomcat and Apache through mod_jk&lt;/h3&gt;
&lt;p&gt;The mod_jk module is an alternative to ModProxy and ModProxyAJP and can be used in their place. It provides the most advanced functionality to connect Apache to Tomcat and provides load balancing and failure detection.&lt;/p&gt;
&lt;p&gt;To install mod_jk, first make sure that you have its dependencies installed. For CentOS 6 you can install the required packages and their dependencies with the command &lt;code&gt;yum install gcc gcc-c++ httpd-devel&lt;/code&gt;. This installs the GNU compiler collection with C++ support (gcc, gcc-c++) and Apache's development tools, including the required apxs tool.&lt;/p&gt;
&lt;p&gt;Next, download mod_jk's latest source from &lt;a href="http://tomcat.apache.org/download-connectors.cgi"&gt;Tomcat's connectors page&lt;/a&gt; and extract it to a temporary directory. Inside the source directory compile and install the software with the commands &lt;code&gt;./configure --with-apxs=http://www.openlogic.com/usr/sbin/apxs &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install&lt;/code&gt;. This should create mod_jk and place it in Apache's modules directory under the name /usr/lib64/httpd/modules/mod_jk.so.&lt;/p&gt;
&lt;p&gt;Once mod_jk is installed you can configure it, via two files. The first, /etc/httpd/conf.d/tomcat.conf, should look like this:&lt;/p&gt;
&lt;pre&gt;LoadModule    jk_module  /usr/lib64/httpd/modules/mod_jk.so
JkWorkersFile /etc/httpd/conf.d/workers.properties
JkLogFile     /var/log/httpd/mod_jk.log
JkLogLevel    info
JkMount /* localserver
&lt;/pre&gt;
&lt;p&gt;The LoadModule directive instructs Apache to load the newly compiled module from /usr/lib64/httpd/modules/mod_jk.so. JkWorkersFile configures the essential mod_jk configuration file, as we'll see in a moment. After that come the logging directives: JkLogFile specifies the log file and JkLogLevel the logging level.&lt;/p&gt;
&lt;p&gt;The last directive, JkMount, has the structure &lt;code&gt;JkMount &lt;em&gt;URLprefix&lt;/em&gt; &lt;em&gt;Workername&lt;/em&gt;&lt;/code&gt;. In this example, any URL request (/*) is forwarded to the worker named localserver. The localserver worker is defined in the file workers.properties, which is the second configuration file we need for mod_jk. It contains the back ends' configuration. Here is an example configuration with only one back-end server, worker:&lt;/p&gt;
&lt;pre&gt;worker.list=localserver
worker.localserver.port=8009
worker.localserver.host=localhost
worker.localserver.type=ajp13
&lt;/pre&gt;
&lt;p&gt;It define the name of the worker, localserver, along with a port (8009), host (localhost), and type (ajp13).&lt;/p&gt;
&lt;p&gt;If you try the previous benchmark tests after installing mod_jk you should see good performance results similar to the ones for ModProxyAJP and AJP13 that complement mod_jk's advanced features for complex setups with multiple workers. In such setups mod_jk provides robust load balancing with failure detection, session stickiness, and work quotas (how much traffic a worker should get according to its predefined load balancing factor). For more information check the official &lt;a href="http://tomcat.apache.org/connectors-doc/reference/printer/workers.html"&gt;worker properties documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Considering the above, it's fair to say that for a simple setup with a pair of Tomcat and Apache servers on the same machine you should use ModProxyAJP and AJP13. However, if you want robust load balancing, it's worth investing in setting up mod_jk.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/277036/Three-ways-to-integrate-Tomcat-and-Apache-for-best-performance-and-features&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/MaHSQWpQKso" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Mon, 25 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:277036</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/277036/Three-ways-to-integrate-Tomcat-and-Apache-for-best-performance-and-features</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/276417/Nine-all-purpose-plugins-for-Vim#Comments</comments><slash:comments>2</slash:comments><title>Nine all-purpose plugins for Vim</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/SwA1D-AbJ-I/Nine-all-purpose-plugins-for-Vim</link><description>&lt;p&gt;In its 22 years of existence, the &lt;a href="http://olex.openlogic.com/packages/vim"&gt;Vim&lt;/a&gt; editor has become the center of an ecosystem of plugins. Whether you are coding or writing a text document, you can probably find a plugin that will make you more productive.&lt;/p&gt;
&lt;p&gt;If you're coding in a specific programming language, you can find multiple plugins that will customize Vim to transform it into a dedicated editor for your language, but you don't have to be so specialized to benefit from many Vim plugins. Consider the following.&lt;/p&gt;
&lt;h3&gt;Pathogen&lt;/h3&gt;
&lt;p&gt;The more plugins you use in Vim, the harder it is to keep them updated or delete them. A number of &lt;a href="http://www.openlogic.com/wazi/bid/262302/Three-tools-for-managing-Vim-plugins"&gt;plugin managers&lt;/a&gt; for Vim can help. The oldest and most popular, &lt;a href="https://github.com/tpope/vim-pathogen"&gt;Pathogen&lt;/a&gt;, simplifies plugin management by requiring that each plugin have its own subdirectory. It is popular among those who prefer to manage plugins for themselves, but appreciate having a tool that simplifies the process.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/gmarik/vundle"&gt;Vundle&lt;/a&gt; ("Vim bUndle") uses the same directory structure as Pathogen, but takes the additional step of requiring modifications to the .vimrc directory in order to allow automatic updates and provide the ability to turn off a plugin without actually deleting it.&lt;/p&gt;
&lt;h3&gt;NERDTree&lt;/h3&gt;
&lt;p&gt;Switching from Vim to a file manager can break your concentration, especially if you are working in a maximized terminal. &lt;a href="https://github.com/scrooloose/nerdtree"&gt;NERDTree&lt;/a&gt; solves the problem by adding a directory tree in a separate pane inside Vim. The tree highlights files, directories, symbolic links, read-only files, and binaries in different colors for easy identification. You can also bookmark files so that you can jump directly to them.&lt;/p&gt;
&lt;p&gt;When you start NERDTree with the command &lt;code&gt;:NERDTree&lt;/code&gt;, it shows the current directory. If you prefer, you can specify a directory or a bookmarked file as the starting point instead by adding its path to the end of the commandYou can also use the command &lt;code&gt;:NERDTreeFind [String]&lt;/code&gt;. to search for a specific file and jump to it.&lt;/p&gt;
&lt;p&gt;If you like the idea of having a file manager within Vim but don't love NERDTree, you have other options. &lt;a href="https://github.com/troydm/easytree.vim"&gt;Easytree&lt;/a&gt;, for instance, has fewer features, while &lt;a href="https://github.com/mihaifm/vimpanel"&gt;Vimpanel&lt;/a&gt; and &lt;a href="https://github.com/gimac/winmanager"&gt;wimanager&lt;/a&gt; have more.&lt;/p&gt;
&lt;h3&gt;YankRing&lt;/h3&gt;
&lt;p&gt;"Yank" is Vim's term for copying or cutting and pasting. A yankring is a retrievable history of yanks, similar to the one provided by Klipper on the KDE desktop.&lt;/p&gt;
&lt;p&gt;By default, Vim stores the last nine yanks. However, with the &lt;a href="https://github.com/chrismetcalf/vim-yankring"&gt;YankRing&lt;/a&gt; plugin, you can reconfigure Vim to store more or fewer. Even more importantly, YankRing allows you to copy or cut in a separate pane or with a series of commands that give you the choice of yanking everything from the current word or line to a range of lines. If you store the ring in a file, you can use it with multiple instances of Vim, which may be especially handy on a network.&lt;/p&gt;
&lt;h3&gt;Surround&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/tpope/vim-surround"&gt;Surround&lt;/a&gt; is useful with many programming languages because it deals with delimiters – characters that appear in pairs to define a string, such as quotation marks, brackets, parentheses, and complete tags in markup languages like HTML and XML. Surround adds, deletes, and replaces delimiters via a series of keyboard commands.&lt;/p&gt;
&lt;p&gt;If you want to compare Surround with similar alternatives, &lt;a href="https://github.com/vim-scripts/closetag.vim"&gt;closetag&lt;/a&gt; and &lt;a href="https://github.com/tpope/vim-ragtag"&gt;ragtag&lt;/a&gt; offer something of the same functionality, specifically for markup languages.&lt;/p&gt;
&lt;h3&gt;Showmarks&lt;/h3&gt;
&lt;p&gt;Marks are bookmarks within a Vim document. You can set a mark by pressing &lt;code&gt;m&lt;/code&gt; followed by another letter that designates the mark. To jump to a mark, enter &lt;code&gt;'&lt;/code&gt; followed by the mark's letter.&lt;/p&gt;
&lt;p&gt;The great weakness of marks is that they are invisible. This limits the number you can use to however many you can remember, and you can easily accidentally overwrite an existing mark by creating another with the same name.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/vimez/vim-showmarks"&gt;Showmarks&lt;/a&gt; allows you to toggle the visibility of marks off and on – and that tiny functionality is enough to increase the usefulness of marks several times over.&lt;/p&gt;
&lt;h3&gt;NERD-commenter&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/scrooloose/nerdcommenter"&gt;NERD-commenter&lt;/a&gt; is a general-purpose plugin designed for writing code or using markup languages. Even if you are not writing code or markup, comments are still helpful when you're collaborating with others on a document. You may also find comments more convenient than storing thoughts in a separate buffer, as the &lt;a href="https://github.com/xolox/vim-notes"&gt;Notes&lt;/a&gt; plugin does.&lt;/p&gt;
&lt;p&gt;NERD-commenter installs with a series of keyboard shortcuts for adding and removing comments based on various selections of words or lines or of cursor position. It supports nested comments, the use of alternate delimiters to mark comments, and selecting the positioning of delimiters.&lt;/p&gt;
&lt;h3&gt;Vim-abolish&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/tpope/vim-abolish"&gt;Vim-abolish&lt;/a&gt; is so elegant that you wonder why no one thought of it before, but it's hard to describe. It has aspects of a word processor's spell checker or autocorrect, but might best be described as a configurable search and replace tool. What makes Vim-abolish so powerful is that it allows you not only to search and replace one word or spelling for another, but also to include all instances of a word. Upper case, lower case, noun and adverb, past and present tense, participles – all can be added to the search and replaced with a few dozen characters.&lt;/p&gt;
&lt;p&gt;Admittedly, you might take a while to learn how to think in the terms necessary to set up a Vim-abolish command, and learning how to construct a command may take some time too. However, once you understand how Vim-abolish works, you will probably find it an invaluable proofreading tool.&lt;/p&gt;
&lt;h3&gt;VimOutliner&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://freecode.com/projects/vimoutliner"&gt;VimOutliner&lt;/a&gt; is exactly what its name suggests: a way to create hierarchial outlines. It is so popular that most major distributions package it, but you must add two lines to your .vimrc file before you can use it:&lt;/p&gt;
&lt;pre&gt;filetype plugin indent on
syntax on
&lt;/pre&gt;
&lt;p&gt;Once you have VimOutliner up and running, creating a new level is as simple as starting a new line with an additional indent and adding a heading. Start a line below a heading with a colon (:), and text will be wrapped automatically and formatted when you export the current document to another format; start a line with a semicolon (;) and you can insert a line break. You can also collapse or open outline levels as useful, with everything color-coded for convenience.&lt;/p&gt;
&lt;p&gt;You can save a VimOutiner document to a file with an .otl extension. However, VimOutliner also includes a series of Python scripts to save to awk, PDF, DocBook, HTML, and LibreOffice Impress formats – the latter presumably chosen because its Outline view is the best outline tool available in the office suite.&lt;/p&gt;
&lt;h3&gt;Gundo&lt;/h3&gt;
&lt;p&gt;Vim supports powerful &lt;a href="http://www.openlogic.com/wazi/bid/188018/"&gt;undo functionality&lt;/a&gt; that tracks not only changes, but branches of changes. However, good luck finding a particular change with vanilla Vim so you can revert to it. If you don't want to simply revert one step at a time until you find what you are looking for, you can try to jump according to your best guess as to the time the change was made. Of course, if you guess wrong, or fail to keep track of what branch you are on, you are more likely to be confused than successful.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://sjl.bitbucket.org/gundo.vim/"&gt;Gundo&lt;/a&gt; eliminates this confusion with a text-based representation of the undo tree and a few simple tools for navigation. At all times, you know exactly where in the undo tree you are, and that allows the undo functions to really come into their own.&lt;/p&gt;
&lt;h3&gt;Learning curves and alternatives&lt;/h3&gt;
&lt;p&gt;Add a few of these plugins, and functionally Vim soon begins to rival a word processor. However, no matter how many plugins you add, Vim is never going to match the convenience of an office suite, even if you use GUI-Vim. Some of these plugins include a lengthy list of keyboard commands that take practice and repeated use to master. However, the control and power they offer makes the effort worthwhile, especially if you work regularly without a display manager.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/276417/Nine-all-purpose-plugins-for-Vim&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/SwA1D-AbJ-I" height="1" width="1"/&gt;</description><dc:creator>Bruce Byfield</dc:creator><pubDate>Thu, 21 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:276417</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/276417/Nine-all-purpose-plugins-for-Vim</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/275172/Clonezilla-vs-FOG-The-clone-wars#Comments</comments><slash:comments>4</slash:comments><title>Clonezilla vs. FOG: The clone wars</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/Lw5hZQnCjbk/Clonezilla-vs-FOG-The-clone-wars</link><description>&lt;p&gt;Computer cloning, also referred to as ghosting or imaging, involves setting up the operating system, drivers, software, and data on one computer, then automatically replicating the same setup on other computers. &lt;a href="http://olex.openlogic.com/packages/clonezilla"&gt;Clonezilla&lt;/a&gt; Server Edition and &lt;a href="http://olex.openlogic.com/packages/freeghost"&gt;FOG&lt;/a&gt; are the most popular open source cloning systems. While both do similar jobs – clone and restore machines over the network using tools and services such as partimage, tftp, and PXE – they go about it very differently. Which is right for you depends on your network's configuration and composition.&lt;/p&gt;
&lt;p&gt;The most visible difference between the two solutions is in their user interfaces. Clonezilla has an archaic ncurses-based interface, while FOG provides a web-based interface that you can access from any computer on the network. It also has a special UI that lets you deploy images from mobile devices.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/fog-UI-resized-600.png" border="0" alt="fog UI resized 600"&gt;&lt;/p&gt;
&lt;p&gt;While both FOG and Clonezilla SE can handle multiple images, FOG is better designed to manage multiple images. With FOG you can logically arrange images in groups, such as Accounts Department or Labs or Lounge. FOG also scales better; it features a &lt;a href="http://www.fogproject.org/wiki/index.php/Managing_FOG#Storage_Management"&gt;storage manager&lt;/a&gt; that can control a group of NFS servers that all host images. Multiple servers can serve images, taking some of the stress off the main FOG server and speeding up cloning, especially in large networks.&lt;/p&gt;
&lt;p&gt;In an enterprise where you have a large number of computers to deploy, the best course is to deploy images across the network, which requires setting up a dedicated cloning server. For Clonezilla SE, this means &lt;a href="http://www.openlogic.com/wazi/bid/188051/With-Clonezilla-Install-Once-and-Clone-Forever"&gt;setting up a Diskless Remote Boot in Linux (DRBL) server&lt;/a&gt; by installing it on top of a Debian or &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt; server. If you manage a small network and don't want to earmark a computer as a permanent DRBL server, you can use the &lt;a href="http://drbl.org/download/"&gt;DRBL live CD&lt;/a&gt; to convert any machine into a server temporarily to broadcast images created by Clonezilla and stored on a local disk to any computer on the network.&lt;/p&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 30%; margin-bottom: 10px; margin-right: 10px; float: left;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;To use a cloning solution effectively, it's best if computers on your network have similar hardware components. If your network is made up of computers with different components, you'd need to manage lots of different images.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;As for FOG, its installation script creates the components required for an imaging server on top of a standard LAMP server. Unlike Clonezilla's DRBL server, the FOG server is designed to integrate with existing network infrastructure such as DHCP and DNS servers, although it can also set these up on its own. Setting up a FOG cloning server is pretty straightforward, but if you're &lt;a href="http://www.fogproject.org/wiki/index.php/Modifying_existing_DHCP_server_to_work_with_FOG"&gt;using an existing DHCP server&lt;/a&gt; you must tweak it to forward PXE traffic to the FOG server, and &lt;a href="http://fogproject.org/forum/threads/firewall-config.27/"&gt;configure the firewall&lt;/a&gt; to pass traffic to the server.&lt;/p&gt;
&lt;p&gt;If all of the machines you want to image are not on your network, you need a solution that can clone offline machines as well. To do that, you create a master image, copy it on to a removable USB disk, and deploy from that. Clonezilla lets you save an image to a disk and then clone it either over the network or by physically going over to the computer. FOG doesn't – you can clone only from an imaging server.&lt;/p&gt;
&lt;p&gt;After an image has been deployed, both Clonezilla SE (with &lt;a href="http://drbl-winroll.org/"&gt;DRBL-Winroll&lt;/a&gt;) and FOG (with its client service) can integrate the cloned machines into an Active Directory domain.&lt;/p&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 35%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Other cloning options&lt;/strong&gt;&lt;br&gt; Clonezilla SE and FOG are designed for cloning and deploying multiple computers over a network, but they both require setting up a dedicated server. This is overkill for situations where you just need to quickly image a disk, as you would for example when switching to a bigger hard drive. In such a situation, you might consider using one of these open source disk cloning applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mondorescue.org/"&gt;Mondo Rescue&lt;/a&gt; – This tool is available in the repos of major desktop distros and can clone your computer to tapes, hard disks, USB devices, and NFS mounts. Unlike other tools, Mondo creates a specialized recovery live CD/DVD based on its own Mindi distro, customized for the computer being backed up.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://redobackup.org/"&gt;Redo Backup and Recovery&lt;/a&gt; – Perhaps the easiest point-and-click cloning solution with a good-looking graphical interface. It can save cloned images on a disk attached to a computer or a network folder. The live CD also has tools such as testdisk and photorec to recover files. Its only limitation is that it's very sensitive to hardware changes and will restore only to identical hardware.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://redobackup.org/"&gt;Trinity Rescue Kit&lt;/a&gt; – Popularly known as TRK, the live distro is primarily designed for rescuing and repairing Windows installations. It's chock-full of tools that can reset forgotten passwords, recover accidentally deleted files and partitions, and scan for viruses and rootkits. Additionally, you can also use the distro to clone Windows machines over the network.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;While that's just about the extent of Clonezilla's capabilities, the FOG service can do a lot more. It can schedule tasks, such as deploying images, from its web interface, and perform several tasks other than imaging, such as installing and managing printers, tracking access to cloned machines, powering up a computer remotely using Wake-On-LAN, and installing applications remotely via a feature called &lt;a href="http://searchwinit.techtarget.com/definition/snap-in"&gt;snap-ins&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With snap-ins you can directly push the executable installer for a simple application to a Windows computer. For a larger application such as Microsoft Office that requires multiple files for installation, you need to use a tool like &lt;a href="http://www.isoft-online.com/"&gt;SFX Maker&lt;/a&gt; instead. FOG snap-ins don't have to be associated with an imaging task, so they can be used for things such as pushing software updates to client computers.&lt;/p&gt;
&lt;p&gt;If you don't need to keep track of machines after cloning them, as might be the case, for example, in a repair or service center, Clonezilla gives you an edge over FOG. With Clonezilla you don't need to register a host with the server before it can be cloned. In contrast, FOG, by default, not only requires hosts to be registered before they are imaged, it also needs to register clients before it deploys images to them – though by using the &lt;a href="http://fogproject.org/wiki/index.php?title=Plugins:_Capone"&gt;Capone plugin&lt;/a&gt; you can override FOG's default behavior and clone a computer without first registering it with the server. Registering hosts has advantages, however, especially on enterprise networks. While registering hosts, FOG records the unique MAC address of their network cards, which reduces the chance of mistakenly deploying an image to the wrong machine.&lt;/p&gt;
&lt;p&gt;While FOG is a fine enterprise imaging solution, it also has many of the features you'd want from a network management app. For example, in addition to options for registering and deploying an image, FOG's menu offers options to wipe a disk, restore deleted files, scan a disk for bad blocks, and run a virus scan using ClamAV.&lt;/p&gt;
&lt;h3&gt;Final word&lt;/h3&gt;
&lt;p&gt;If you're choosing between Clonezilla and FOG and you have machines that aren't connected to a network, you have no option but to use Clonezilla. You have to take an image with you and deploy it on each machine, but that's still faster than preparing each disk and installing and setting up an operating system on each individual client.&lt;/p&gt;
&lt;p&gt;Clonezilla SE makes the most sense for networks with clients that don't require much administration after being imaged, such as those in Internet cafes, libraries, and school labs. If you need to look after machines after they've been cloned, it's best to go with FOG. Its post image options are excellent, and you can deploy machines without leaving your own desk.&lt;/p&gt;
&lt;p&gt;The bottom line is that, while Clonezilla works best for offline computers and individuals, FOG has all the features you need to manage and deploy images in an enterprise.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/275172/Clonezilla-vs-FOG-The-clone-wars&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/Lw5hZQnCjbk" height="1" width="1"/&gt;</description><dc:creator>Mayank Sharma</dc:creator><pubDate>Mon, 18 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:275172</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/275172/Clonezilla-vs-FOG-The-clone-wars</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/274352/Migrating-from-MySQL-to-PostgreSQL#Comments</comments><slash:comments>1</slash:comments><title>Migrating from MySQL to PostgreSQL</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/Tei8Mtd8EjM/Migrating-from-MySQL-to-PostgreSQL</link><description>&lt;p&gt;&lt;a href="http://olex.openlogic.com/packages/mysql"&gt;MySQL&lt;/a&gt; is a fine database, but the open source community has been nervous about its future since it was acquired by Oracle in 2009. Some users have sought alternatives in MySQL forks such as &lt;a href="http://olex.openlogic.com/packages/mariadb"&gt;MariaDB&lt;/a&gt;. Others have considered migration to &lt;a href="http://olex.openlogic.com/packages/postgresql"&gt;PostgreSQL&lt;/a&gt;, a mature database with a track record of more than 15 years. If you want to explore PostgreSQL, here's how to get started.&lt;/p&gt;
&lt;p&gt;You can install and run PostgreSQL on the same server as MySQL, which makes the migration easier. A stable version of PostgreSQL is available through the package managers of all major Linux distributions. If you want to be sure to get the latest features and best performance, you can install the most recent version, which is usually available from third-party sources.&lt;/p&gt;
&lt;p&gt;To install the current version of PostgreSQL, 9.2, on &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt;, first add &lt;a href="http://yum.postgresql.org/"&gt;PostgreSQL's repository&lt;/a&gt; to your .repo file with the command &lt;code&gt;rpm -ivh http://yum.postgresql.org/9.2/redhat/rhel-6-x86_64/pgdg-redhat92-9.2-7.noarch.rpm&lt;/code&gt;. You can then install the PostgreSQL packages with the command &lt;code&gt;yum groupinstall "PostgreSQL Database Server PGDG"&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Before you start PostgreSQL for the first time, you have to have to initialize a new server instance and its database with the command &lt;code&gt;service postgresql-9.2 initdb&lt;/code&gt;. After that you can start the server with the command &lt;code&gt;service postgresql-9.2 start&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To configure PostgreSQL to start and stop with the system, run the command &lt;code&gt;chkconfig postgresql-9.2 on&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Migrating data from MySQL to PostgreSQL&lt;/h3&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 33%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Working with PostgreSQL&lt;/strong&gt;&lt;br&gt;PostgreSQL provides a command-line client, /usr/bin/psql, that's similar to the MySQL client /usr/bin/mysql. By default, PostgreSQL allows only the system user postgres to access the server, and not the root user. To use /usr/bin/psql you should switch to the postgres user with the command &lt;code&gt;su postgres&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you try to use /usr/bin/psql as root, you will get the error &lt;code&gt;psql: FATAL: role "root" does not exist&lt;/code&gt;. This means the root user has not been given a PostgreSQL role, meaning it has no rights. While you could create a role for root, it's not recommended from a security point of view; stick to the special postgres user. For more information, check the PostgreSQL documentation for &lt;a href="http://www.postgresql.org/docs/9.2/interactive/user-manag.html"&gt;database roles&lt;/a&gt;.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Once you have PostgreSQL installed you can start your migration. To illustrate how you can migrate data from MySQL to PostgreSQL I will use the freely available sample &lt;a href="https://launchpad.net/test-db/"&gt;employees database&lt;/a&gt;, which offers large amounts of diverse data. To import it into MySQL, first download &lt;a href="https://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2"&gt;the full archive&lt;/a&gt;, extract it, and run the command &lt;code&gt;mysql -t &amp;lt; employees.sql&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Plenty of tools are available for converting MySQL data to PostgreSQL. &lt;a href="http://pgfoundry.org/frs/download.php/1535/mysql2pgsql.perl"&gt;mysql2pgsql&lt;/a&gt;, for instance, is a Perl script that takes as input a MySQL data dump file and converts it to PostgreSQL-compatible format. You can find other tools in the official PostgreSQL documentation about &lt;a href="http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL"&gt;converting from other databases&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To begin the conversion, first create a dump of your MySQL data. For the employees database, run the command &lt;code&gt;mysqldump employees &amp;gt; employees_mysql.sql&lt;/code&gt;. When the dump completes, start the PostgreSQL conversion with the command &lt;code&gt;./mysql2pgsql.perl employees_mysql.sql employees_postgre.sql&lt;/code&gt;. This command creates a new file called employees_postgre.sql that contains all the statements needed to import your old data into PostgreSQL.&lt;/p&gt;
&lt;p&gt;To perform the data import, first create the employees database in PostgreSQL with the Linux command &lt;code&gt;/usr/bin/createdb employees&lt;/code&gt;. Then use the command &lt;code&gt;/usr/bin/psql employees &amp;lt; employees_postgre.sql&lt;/code&gt; to import the previously converted dump.&lt;/p&gt;
&lt;p&gt;Once the import completes you should find that the databases in MySQL and PostgreSQL are the same. You can make a simple check by looking at the number of rows in the salaries table. First check it in MySQL:&lt;/p&gt;
&lt;pre&gt;mysql&amp;gt; select count(*) from salaries;
+----------+
| count(*) |
+----------+
|  2844047 |
+----------+
&lt;/pre&gt;
&lt;p&gt;Then in PostgreSQL:&lt;/p&gt;
&lt;pre&gt;employees=# select count(*) from salaries;
  count  
---------
 2844047
&lt;/pre&gt;
&lt;p&gt;You can try more complex comparisons, such as looking for specific records inside the employees table. In MySQL an example query looks like:&lt;/p&gt;
&lt;pre&gt;mysql&amp;gt; select * from employees where first_name = 'Ioana' and last_name = 'Tsukuda';
+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
| 496865 | 1961-09-17 | Ioana      | Tsukuda   | M      | 1994-10-13 |
+--------+------------+------------+-----------+--------+------------+
&lt;/pre&gt;
&lt;p&gt;Its analogue in PostgreSQL with exactly the same syntax should return the same result:&lt;/p&gt;
&lt;pre&gt;employees=# select * from employees where first_name = 'Ioana' and last_name = 'Tsukuda';
 emp_no | birth_date | first_name | last_name | gender | hire_date  
--------+------------+------------+-----------+--------+------------
 496865 | 1961-09-17 | Ioana      | Tsukuda   | M      | 1994-10-13
&lt;/pre&gt;
&lt;h3&gt;Connecting your application to PostgreSQL&lt;/h3&gt;
&lt;p&gt;Once you ensure your data is properly migrated to PostgreSQL you can proceed with connecting your application to it.&lt;/p&gt;
&lt;p&gt;Some applications, such as &lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, support PostgreSQL by default, while others, such as &lt;a href="http://olex.openlogic.com/packages/wordpress"&gt;WordPress&lt;/a&gt;, require you to install an &lt;a href="http://wordpress.org/extend/plugins/postgresql-for-wordpress/"&gt;additional plugin&lt;/a&gt;. In any case, PostgreSQL is widely supported, and it should be relatively easy to find support for your application and its programming language.&lt;/p&gt;
&lt;p&gt;When you create applications that use a database, you should design them to allow later developers to easily migrate from one database to another. If your applications use a &lt;a href="http://en.wikipedia.org/wiki/Database_abstraction_layer"&gt;database abstraction level&lt;/a&gt;, you should be able to just change the database driver and the connection string and start using a different database, such as PostgreSQL. For example, if you are using PHP on CentOS, install the &lt;code&gt;php-pgsql&lt;/code&gt; package to get the PostgreSQL database module (driver) for PHP. Once you have it installed (&lt;code&gt;yum install -y php-pgsql&lt;/code&gt;), you can establish a PostgreSQL connection in PHP with a connection string similar to &lt;code&gt;$connection=pg_connect('dbname=employees&amp;nbsp;user=&lt;em&gt;test&lt;/em&gt;&amp;nbsp;password=&lt;em&gt;example&lt;/em&gt;');&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If your application lacks a database abstraction layer, all SQL statements might be hard-coded with MySQL specifics. In such a case you'll have a hard time moving away from MySQL because almost every SQL statement may require adjustment. But nothing is impossible with enough determination, time, and budget. Even if immediate migration looks difficult, it's good to know that there is an alternative such as PostgreSQL to which you can turn in future.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/274352/Migrating-from-MySQL-to-PostgreSQL&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/Tei8Mtd8EjM" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Thu, 14 Mar 2013 10:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:274352</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/274352/Migrating-from-MySQL-to-PostgreSQL</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/273437/Three-simple-tools-for-backing-up-MySQL-databases#Comments</comments><slash:comments>3</slash:comments><title>Three simple tools for backing up MySQL databases</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/7AhX2ez-t24/Three-simple-tools-for-backing-up-MySQL-databases</link><description>&lt;p&gt;One of the most important responsibilities of any administrator is to make regular backups. But unlike backing up regular data, backing up databases isn't a straightforward affair. Designing an effective strategy for taking backups of production &lt;a href="http://olex.openlogic.com/packages/mysql"&gt;MySQL&lt;/a&gt; servers depends on a lot of factors. Depending on your situation, your best MySQL backup tool might be mysqldump, &lt;a href="http://sourceforge.net/projects/automysqlbackup/"&gt;AutoMySQLBackup&lt;/a&gt;, or &lt;a href="http://olex.openlogic.com/packages/mysqlworkbench"&gt;MySQL Workbench&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The easiest and safest way to back up a database is to shut down the MySQL server. This ensures you have a consistent copy of the data, since you don't have to worry about parts of the database being modified while it's being backed up. The backups themselves will be completed faster than on a production server, as the server isn't handling requests from other applications.&lt;/p&gt;
&lt;p&gt;That said, taking a database server offline isn't a practical solution for most enterprise deployments. So you'll want to use a solution that lets you take backups of a production server without taking it offline.&lt;/p&gt;
&lt;table style="border: 1px solid #c5cac5; background: #e5e8eb; width: 40%; margin-bottom: 10px; margin-left: 10px; float: right;"&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="padding-top: 10px; padding-left: 10px; padding-right: 10px;"&gt;
&lt;p&gt;&lt;strong&gt;Types of backups&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hot backup – A hot backup is a backup of a running database. During a hot backup, neither reads nor writes to the database are blocked. This is the best option for huge databases that can take days or weeks to back up, as well as deployments that can't afford any downtime. However, it's risky, and if not implemented properly it can negatively affect performance.&lt;/li&gt;
&lt;li&gt;Warm backup – A warm backup is also a backup of a database that is still running, but during a warm backup, only read queries are allowed; write queries are blocked from modifying a database. This option works well for most deployments, and you can use a combination of tools to speed up the backup process for large databases.&lt;/li&gt;
&lt;li&gt;Cold backup – A cold backup is a backup performed while the database is shut down. This makes it easy to make a consistent copy of your data. The biggest disadvantage of this method is that the server is not accessible during the time the backup is performed. This approach works best for databases that hold mostly static information, such as a database of employees.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Then there's the question of how you want to back up the database. There are two major ways to back up MySQL's data: either by creating a logical backup or by copying the raw files. A logical backup saves information that represents the database structures. It's made up of SQL statements such as CREATE DATABASE and INSERT. The obvious advantage of such a backup is that you can make changes to the data with a text editor or using tools such as grep. A raw backup, on the other hand, is a backup of the disk partitions of the database server.&lt;/p&gt;
&lt;p&gt;Both methods have advantages and disadvantages. Logical backups are simpler, you can restore them by simply piping them into the MySQL server, and logical backups are more compatible between different versions of MySQL. It's actually a standard practice to restore a database from a logical backup when upgrading from one MySQL release to another. But depending on the size and complexity of the database, taking a raw backup and restoring it can be much faster than working with a logical backup.&lt;/p&gt;
&lt;h3&gt;Take backups with mysqldump&lt;/h3&gt;
&lt;p&gt;The default backup tool that ships with MySQL server is the command-line &lt;a href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html"&gt;mysqldump&lt;/a&gt; program. With it you can create a logical backup of all the databases on a server, or individual databases, or only particular tables.&lt;/p&gt;
&lt;p&gt;The output dumped by the tool contains all the commands required to recreate the database, complete with tables filled with the original data.&lt;/p&gt;
&lt;p&gt;Using the tool is pretty simple:&lt;/p&gt;
&lt;pre&gt;$ mysqldump --user=root --password --all-databases &amp;gt; dump.sql &lt;/pre&gt;
&lt;p&gt;This command creates a file named dump.sql in the current directory that contains all the SQL commands to recreate the database and all its tables and fill it with the original data. You can browse the contents of the file with the less command. Here's a brief snippet:&lt;/p&gt;
&lt;pre&gt;$ less dump.sql
-- MySQL dump 10.13  Distrib 5.5.29, for linux2.6 (i686)
--
-- Host: localhost    Database: 
-- ------------------------------------------------------
-- Server version       5.5.29

--
-- Current Database: `drupal7`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `drupal7` /*!40100 DEFAULT CHARACTER SET latin1 */;

USE `drupal7`;

--
-- Table structure for table `actions`
--

DROP TABLE IF EXISTS `actions`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `actions` (
  `aid` varchar(255) NOT NULL DEFAULT '0',
  `parameters` longblob NOT NULL,
  `label` varchar(255) NOT NULL DEFAULT '0',
  PRIMARY KEY (`aid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Stores action information.';
/*!40101 SET character_set_client = @saved_cs_client */;
&lt;/pre&gt;
&lt;p&gt;The tool has an extensive list of options, some more commonly used than others. If you want to back up only particular databases, instead of the &lt;code&gt;--all-databases&lt;/code&gt; option use the &lt;code&gt;--databases&lt;/code&gt; option and specify the name of the databases you want to back up. To ensure the backups are consistent, use the &lt;code&gt;--lock-all-tables&lt;/code&gt; option to lock all tables across all databases.&lt;/p&gt;
&lt;p&gt;The mysqldump tool works on all the MySQL storage engines. It can do a warm backup at acceptable backup speeds but drags its feet when restoring the database. It works best for smaller databases, and its biggest advantage is that it's scriptable.&lt;/p&gt;
&lt;h3&gt;Script backups with AutoMySQLBackup&lt;/h3&gt;
&lt;p&gt;If mysqldump works for your MySQL setup, you can either script it for taking automated backups, or use AutoMySQLBackup. It's a clever little script, based on mysqldump, that does a lot of heavy lifting. It can back up a single database or multiple databases and save them in separate compressed files. Using the script you can easily set up incremental backups that are automatically rotated.&lt;/p&gt;
&lt;p&gt;To use the script, download and unpack it. It has an install.sh script that installs the script under /etc/automysqlbackup directory. Edit the configuration file under this directory as per your setup and requirements. The various configuration options are explained in the script itself, but here are the most important ones.&lt;/p&gt;
&lt;p&gt;To make sure the script can connect to the MySQL server, make sure you customize the following variables as per your setup:&lt;/p&gt;
&lt;pre&gt;CONFIG_mysql_dump_username='root'
CONFIG_mysql_dump_password='not$telling'
CONFIG_mysql_dump_host='localhost'
&lt;/pre&gt;
&lt;p&gt;If you want you can also change the directory where the backups are stored by specifying the location in the &lt;code&gt;CONFIG_backup_dir&lt;/code&gt; variable. Similarly, if you want only a particular list of databases to be backed up instead of everything, specify them with the &lt;code&gt;CONFIG_db_names&lt;/code&gt; variables. Or, you can specify the databases and tables you wish to exclude with the &lt;code&gt;CONFIG_db_exclude&lt;/code&gt; and &lt;code&gt;CONFIG_table_exclude&lt;/code&gt; variables.&lt;/p&gt;
&lt;p&gt;To set up a rotation policy, you need to tweak the appropriate variables. For example, if you want to do monthly backups on the 28th of every month, weekly backups on Sundays, and keep daily backups for seven days, weekly backups for 14 days, and monthly backups for 30 days, change the variables thusly:&lt;/p&gt;
&lt;pre&gt;CONFIG_do_monthly="28"
CONFIG_do_weekly="7"
CONFIG_rotation_daily=7
CONFIG_rotation_weekly=14
CONFIG_rotation_monthly=30
&lt;/pre&gt;
&lt;p&gt;Once the file has been configured, test it by invoking it manually with &lt;code&gt;# automysqlbackup /etc/automysqlbackup/dbserver.conf&lt;/code&gt;, assuming dbserver.conf is the name of our AutoMySQLBackup configuration file. It should create compressed logical backups of the databases in the appropriate directories.&lt;/p&gt;
&lt;p&gt;When you're satisfied with the command, you can automate the process by creating a backup script and use cron to run that script daily. The README file bundled with AutoMySQLBackup includes a simple but effective backup script.&lt;/p&gt;
&lt;h3&gt;Backups with MySQL Workbench&lt;/h3&gt;
&lt;p&gt;Both mysqldump and AutoMySQLBackup rely on command-line tools to restore the dumps. If you prefer a graphical user interface, there's a GUI backup tool you can use to restore logical backups – among many other things.&lt;/p&gt;
&lt;p&gt;If you work with MySQL databases, chances are you use the graphical &lt;a href="http://olex.openlogic.com/packages/mysqlworkbench"&gt;MySQL Workbench&lt;/a&gt; database design tool. In addition to querying and designing databases, you can also use the tool to create (and restore) logical backups of the databases.&lt;/p&gt;
&lt;!-- mysql-workbench.png --&gt;
&lt;p&gt;&lt;img src="http://www.openlogic.com/Portals/172122/images/mysql-workbench-resized-600.png" border="0" alt="mysql workbench resized 600"&gt;&lt;/p&gt;
&lt;p&gt;MySQL Workbench's main interface is divided into three categories based on function. The backup options are housed under the Server Administration section. To back up your databases, connect to the server from under this category. You will then be switched to a tab that lists all the server administration tools.&lt;/p&gt;
&lt;p&gt;Click on the Data Export option in the left pane. Select the databases and tables you want to back up from the list shown in the right pane. When specifying the destination of the backups, MySQL Workbench lets you specify whether you want to export the backup to a folder (where each table is written to a separate file) or to a single self-contained file.&lt;/p&gt;
&lt;p&gt;To restore databases, switch to the Data Import/Restore option, point to the location where you've stored the backup dumps, and Workbench will display the backed-up databases and tables. You can select the tables you wish to import and they will be restored.&lt;/p&gt;
&lt;h3&gt;Other backup options&lt;/h3&gt;
&lt;p&gt;These three options for creating warm logical backups of databases should work for most enterprise users, but if you need to create a consistent hot backup of your databases, you can turn to the snapshot functionality of your filesystem.&lt;/p&gt;
&lt;p&gt;Filesystems such as &lt;a href="http://www.freebsd.org/doc/handbook/filesystems-zfs.html"&gt;FreeBSD's ZFS&lt;/a&gt; have native support for creating snapshots, and you can also create them using the &lt;a href="http://en.wikipedia.org/wiki/Logical_Volume_Manager_%28Linux%29"&gt;Logical Volume Manager&lt;/a&gt; (LVM) on Linux.&lt;/p&gt;
&lt;p&gt;But filesystem snapshots are still not an ideal solution for taking hot backups. For that, you'd need a commercial product such as &lt;a href="http://www.mysql.com/products/enterprise/backup.html"&gt;MySQL Enterprise Backup&lt;/a&gt; or &lt;a href="http://www.zmanda.com/zrm-mysql-enterprise.html"&gt;Zmanda Recovery Manager&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/273437/Three-simple-tools-for-backing-up-MySQL-databases&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/7AhX2ez-t24" height="1" width="1"/&gt;</description><dc:creator>Mayank Sharma</dc:creator><pubDate>Mon, 11 Mar 2013 10:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:273437</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/273437/Three-simple-tools-for-backing-up-MySQL-databases</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/272031/Replacing-MySQL-with-MariaDB#Comments</comments><slash:comments>0</slash:comments><title>Replacing MySQL with MariaDB</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/AT5FlAxGLV4/Replacing-MySQL-with-MariaDB</link><description>&lt;p&gt;For years, &lt;a href="http://olex.openlogic.com/packages/mysql"&gt;MySQL&lt;/a&gt; has been the king of open source database servers. It powers a large part of the web and numerous applications worldwide. However, concerns about the future of MySQL since its acquisition by Oracle, combined with an increasing demand for performance and scalability, have driven people to consider alternative options, such as &lt;a href="http://olex.openlogic.com/packages/postgresql"&gt;PostgreSQL&lt;/a&gt; and &lt;a href="http://olex.openlogic.com/packages/mongodb"&gt;MongoDB&lt;/a&gt;. Switching to either of those alternatives, however, is not a simple proposition. &lt;a href="http://olex.openlogic.com/packages/mariadb"&gt;MariaDB&lt;/a&gt;, by contrast, offers enhanced performance in a DBMS that can be a drop-in replacement for MySQL.&lt;/p&gt;
&lt;p&gt;MySQL's creator, Michael "Monty" Widenius, started working on MariaDB in 2009 as a fork of MySQL, and supports it via his company, &lt;a href="http://montyprogram.com/"&gt;Monty Program Ab&lt;/a&gt;. In late 2012, the nonprofit &lt;a href="https://mariadb.org/foundation/"&gt;MariaDB Foundation&lt;/a&gt; was founded to support the development of the database and manage the MariaDB trademark. All code for the project is open source, distributed under a GPLv2, LGPL, or BSD license, and the Foundation is commited to keep the development open to the community. Besides transparency, the project also aims to improve the quality of the database with timely bug fixes and stability improvements. The next versions of &lt;a href="http://olex.openlogic.com/packages/fedora_project/"&gt;Fedora&lt;/a&gt; and &lt;a href="http://olex.openlogic.com/packages/suselinux"&gt;openSUSE&lt;/a&gt; will include both MySQL and MariaDB, but will offer MariaDB as the default.&lt;/p&gt;
&lt;h3&gt;Compatible, yet improved&lt;/h3&gt;
&lt;p&gt;The biggest strength of MariaDB is, of course, its compatibility with MySQL. It is a drop-in replacement for the same version of MySQL; that is, if an application works with MySQL 5.5, it should work with MariaDB 5.5 without any modification. Even the names of the command tools are the same – you interact with MariaDB databases via the &lt;code&gt;mysql&lt;/code&gt; command, and perform backups with &lt;code&gt;mysqldump&lt;/code&gt;. Developers and system administrators should feel right at home, with minimal adjustments to their familiar workflow. I've tested some open source applications by replacing MySQL with MariaDB – including &lt;a href="http://olex.openlogic.com/packages/wordpress"&gt;WordPress&lt;/a&gt;, &lt;a href="http://olex.openlogic.com/packages/drupal"&gt;Drupal&lt;/a&gt;, &lt;a href="http://olex.openlogic.com/packages/phpmyadmin"&gt;phpMyAdmin&lt;/a&gt;, &lt;a href="http://www.adminer.org/"&gt;Adminer&lt;/a&gt;, and software I've written – without problems. The project offers &lt;a href="https://kb.askmonty.org/en/works-with-mariadb/"&gt;a list of open source applications that officially support MariaDB&lt;/a&gt; and a detailed &lt;a href="https://kb.askmonty.org/en/mariadb-versus-mysql-compatibility/"&gt;compatibility list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The core of any database system is its data storage engine, and MariaDB offers several powerful engines to choose from, including the standard MyISAM, Blackhole, CSV, Memory, and Archive engines. A new storage engine, &lt;a href="https://kb.askmonty.org/en/aria-faq/"&gt;Aria&lt;/a&gt; (previously known as Maria), was developed with the goal of becoming the default non-transactional &lt;em&gt;and&lt;/em&gt; transactional engine for MariaDB, and might be included in future versions of MySQL too. The current version of Aria offers a crash-free alternative to MyISAM, and support for transactions and additional features is planned for the next version. The &lt;a href="http://www.percona.com/software/percona-xtradb"&gt;Percona XtraDB&lt;/a&gt; engine is included as a replacement for InnoDB, MySQL's default engine since 5.5. XtraDB is a faster version of InnoDB, designed for more efficient scalability on modern multicore systems. It is also backward-compatible with InnoDB. The current development version, MariaDB-10.0, also includes the &lt;a href="http://cassandra.apache.org/"&gt;Apache Cassandra&lt;/a&gt; NoSQL storage engine, and more NoSQL storage options are promised for future versions. You can find all the storage engines included in MariaDB in the list of &lt;a href="https://kb.askmonty.org/en/mariadb-vs-mysql-features/"&gt;feature differences&lt;/a&gt; between the two databases.&lt;/p&gt;
&lt;p&gt;MySQL is not a slow database, and MariaDB aims to improve performance further. The project's blog offers some &lt;a href="http://blog.mariadb.org/sysbench-oltp-mysql-5-6-vs-mariadb-10-0/"&gt;benchmarks comparing MariaDB 5.5 and 10.0 with MySQL 5.5 and 5.6&lt;/a&gt;. MariaDB outperforms MySQL in most of the tests. &lt;a href="http://lists.wikimedia.org/pipermail/wikitech-l/2012-December/064994.html"&gt;A post&lt;/a&gt; by Asher Feldman of Wikimedia largely verifies the results of that benchmark.&lt;/p&gt;
&lt;p&gt;One feature of MariaDB that can greatly improve performance is the option of running server threads in a &lt;a href="https://kb.askmonty.org/en/thread-pool-in-mariadb-55/"&gt;thread pool&lt;/a&gt;. This feature is available in the commercial, closed source versions of MySQL as a plugin, but the MariaDB implementation is more efficient and built-in. Thread pools offer better system resource management and can make a big difference in most work loads, especially on busy servers. To enable a thread pool, just add &lt;code&gt;thread_handling = pool-of-threads&lt;/code&gt; to the MariaDB configuration file, my.cnf, on Unix-like systems. It is enabled by default in the Windows version.&lt;/p&gt;
&lt;p&gt;MariaDB also includes &lt;a href="https://kb.askmonty.org/en/user-statistics/"&gt;user statistics&lt;/a&gt;, a diagnostic feature that is also available as a &lt;a href="http://www.percona.com/doc/percona-server/5.5/diagnostics/user_stats.html?id=percona-server:features:userstatv2&amp;amp;redirect=1"&gt;patch&lt;/a&gt; for MySQL 5.5. Combined with an automated, scripted process, userstat can be a powerful tool for monitoring server activity. To enable statistics to be gathering, add &lt;code&gt;userstat = 1&lt;/code&gt; in my.cnf. Userstat adds several new information schema tables and new &lt;code&gt;FLUSH&lt;/code&gt; and &lt;code&gt;SHOW&lt;/code&gt; commands. Enter &lt;code&gt;SELECT * FROM INFORMATION_SCHEMA.USER_STATISTICS\G&lt;/code&gt; or &lt;code&gt;SHOW USER_STATISTICS\G&lt;/code&gt; at the &lt;code&gt;mysql&lt;/code&gt; prompt to view information about users' activity on your server.&lt;/p&gt;
&lt;h3&gt;Installation&lt;/h3&gt;
&lt;p&gt;Future versions of most Linux distributions and BSDs will ship MariaDB packages in their official repositories, but at the moment, distro availability is &lt;a href="https://kb.askmonty.org/en/distributions-which-include-mariadb/"&gt;limited&lt;/a&gt;. However, the project offers prebuilt packages for popular distributions and a nice &lt;a href="https://downloads.mariadb.org/mariadb/repositories/"&gt;repository configuration&lt;/a&gt; tool to help you select the right repository for your distribution. Considering the slow pace of updates in server-oriented distributions, including RHEL and &lt;a href="http://olex.openlogic.com/packages/centos"&gt;CentOS&lt;/a&gt;, I don't expect to see MariaDB RPMs in official repos soon. Luckily, MariaDB offers long-term &lt;a href="https://kb.askmonty.org/en/mariadb-deprecation-policy/"&gt;support&lt;/a&gt; for updates on RHEL, CentOS, and Ubuntu LTS. If you just want to test how MariaDB behaves on your current setup without disrupting your installation, you can &lt;a href="https://kb.askmonty.org/en/installing-mariadb-alongside-mysql/"&gt;install it alongside MySQL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It's simple to install MariaDB on a CentOS 6 (64-bit) server. If MySQL is already installed on the server and you want to replace it with MariaDB, you should back up /etc/my.cnf and /var/lib/mysql beforehand, then uninstall MySQL with &lt;code&gt;yum erase mysql-server mysql&lt;/code&gt;. Using the repo config tool, create a repo entry for yum and saved it as /etc/yum.repos.d/MariaDB.repo:&lt;/p&gt;
&lt;pre&gt;[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/5.5/centos6-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
&lt;/pre&gt;
&lt;p&gt;After that, just run &lt;code&gt;yum install MariaDB-server MariaDB-client&lt;/code&gt;. You can also try &lt;code&gt;yum install mysql&lt;/code&gt; to install MariaDB or just &lt;code&gt;yum update&lt;/code&gt; if MySQL is already installed, but currently doing so installs the &lt;a href="https://kb.askmonty.org/en/galera/"&gt;Galera&lt;/a&gt; version of MariaDB, which I'll discuss in a moment, so it is better to be explicit about what you want. If you prefer to create your own RPM packages from source, you can follow the project's detailed &lt;a href="https://kb.askmonty.org/en/source-building-mariadb-on-centos/"&gt;instructions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To migrate your previous MySQL installation, overwrite the fresh /etc/my.cnf with your backup. Optionally, you can also break your my.cnf file into multiple configuration files in /etc/my.cnf.d. After starting the server process you should run &lt;code&gt;mysql_upgrade&lt;/code&gt;, as you would with any MySQL updates between major versions. You cannot undo this last step, so make sure you have backups of your databases before proceeding. Running &lt;code&gt;mysql -e 'SHOW GLOBAL VARIABLES LIKE "version"'&lt;/code&gt; will show you the version of your newly installed MariaDB server.&lt;/p&gt;
&lt;h3&gt;MariaDB for the enterprise&lt;/h3&gt;
&lt;p&gt;Large database installations often utilize multiple servers with replication, for extended availability and increased performance. The standard replication mechanisms of MySQL and PostgreSQL are, mainly, asynchronous. Writes to the database occur on a master server initially, and then propagate to one or more slave servers, which are used only for reading data. Another approach is the multi-master topology, which can offer seamless failover, at least in theory. However, due to the asynchronous nature of current replication methods, it is easy for servers to get out of sync and cause more problems.&lt;/p&gt;
&lt;p&gt;The &lt;a href="https://kb.askmonty.org/en/what-is-mariadb-galera-cluster/"&gt;MariaDB Galera&lt;/a&gt; cluster aims to fix this problem by offering true synchronous replication between multiple master servers. Any changes to the database are committed to all nodes simultaneously, via certification-based replication. Synchronous replication offers great benefits in enterprise installations. Applications with many client write transactions can scale to previously unimagined levels by distributing the transactions across the slave nodes of the cluster. Even traditional master-slave designs can benefit from synchronous replication with zero slave lag.&lt;/p&gt;
&lt;p&gt;The Galera cluster is still under development, although at the time of this writing it is considered release-candidate quality. To test it, you need at least three server nodes to form the database cluster. Instead of the &lt;em&gt;MariaDB-server&lt;/em&gt; package you need to install &lt;em&gt;MariaDB-Galera-server&lt;/em&gt;, along with the &lt;em&gt;galera&lt;/em&gt; package, which offers the replication engine (wsrep). The current implementation supports only InnoDB and XtraDB.&lt;/p&gt;
&lt;p&gt;Besides speed and scalability, enterprise database installations require premium support services. An increasing number of &lt;a href="https://mariadb.org/en/service-providers/"&gt;service providers&lt;/a&gt; offer support for MariaDB. Corporations with large investment in MariaDB can also support the Foundation and help move the development of the database forward.&lt;/p&gt;
&lt;p&gt;MariaDB has already made its mark in the database ecosystem as a worthy replacement for MySQL, and you can expect its adoption to keep increasing in the future. After all, having a tuple of high-quality open source databases to choose from is not a bad thing.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/272031/Replacing-MySQL-with-MariaDB&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/AT5FlAxGLV4" height="1" width="1"/&gt;</description><dc:creator>Manolis Tzanidakis</dc:creator><pubDate>Thu, 07 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:272031</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/272031/Replacing-MySQL-with-MariaDB</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/271899/BackTrack-and-its-tools-can-protect-your-environment-from-remote-intrusions#Comments</comments><slash:comments>0</slash:comments><title>BackTrack and its tools can protect your environment from remote intrusions</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/vbiPVybXpPs/BackTrack-and-its-tools-can-protect-your-environment-from-remote-intrusions</link><description>&lt;p&gt;Attackers commonly look for remote vulnerabilities in order to compromise the resources on your network. &lt;a href="http://olex.openlogic.com/packages/backtracklinux"&gt;BackTrack Linux&lt;/a&gt;, a security-testing distribution, can help you inspect your network and servers for remote security weaknesses and potential vulnerabilities.&lt;/p&gt;
&lt;p&gt;BackTrack, which is based on Ubuntu, bundles all the tools necessary for penetration testing and security audits. You don't really have to run BackTrack to use the tools it provides, but booting up a BackTrack live CD lets you get started in no time.&lt;/p&gt;
&lt;p&gt;A word of caution before you start: Scanning your network may take system and network resources. Make sure to fully coordinate your actions inside your company and inform your management.&lt;/p&gt;
&lt;h3&gt;Exploring Your Environment With Nmap&lt;/h3&gt;
&lt;p&gt;One of the first tools you'll want to try is &lt;a href="http://olex.openlogic.com/packages/nmap"&gt;Nmap&lt;/a&gt;, a powerful, smart, command-line network scanner. In essence, Nmap shows open ports and some information about the services listening on these ports.&lt;/p&gt;
&lt;p&gt;Nmap comes with a lot of useful options enabled by default. For instance, port randomization, which randomizes the order of the ports being scanned, prevents simple intrusion detection and protection systems from detecting and blocking you while you're probing. Some other useful options include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;--script – performs the scan with the aid of a set of scripts. Nmap comes bundles with a few sets of scripts categorized according to their use, such as for DOS, brute force, and other weakness detection. You can find the full list on the home page of the &lt;a href="http://nmap.org/nsedoc/"&gt;Nmap Scripting Engine&lt;/a&gt;. If you are not sure what scripts to use, choose the &lt;a href="http://nmap.org/nsedoc/categories/default.html"&gt;default&lt;/a&gt;, which is more informative and less intrusive than some other options.&lt;/li&gt;
&lt;li&gt;-p – specifies which ports you are interested it. Most legitimate services run within the port range of 1:10000 for UDP and TCP protocols. Scanning a larger range requires more time and resources.&lt;/li&gt;
&lt;li&gt;-sV – shows service and version information for the open ports. This is useful to show whether a service is listening on a non-default port, such as Apache listening on TCP port 8080, and the version information may indicate outdated software and potential vulnerabilities. If you detect such outdated applications with Nmap, make sure to patch them as soon as possible.
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;target – defines the target host or network as the final argument of your Nmap command.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Put the above options together and you get a command like:&lt;/p&gt;
&lt;pre&gt;nmap --script=default -p U:1-10000,T:1-10000 -sV 192.168.1.0/24&lt;/pre&gt;
&lt;p&gt;In this case the target is an internal, private network (192.168.1.0/24). If you are looking for truly remote vulnerabilities you should perform the scan from outside your local network. Still, internal scans are also useful and can show unnecessary exposure of services, which is always a security risk.&lt;/p&gt;
&lt;p&gt;The output of this example is similar to:&lt;/p&gt;
&lt;pre&gt;...
Nmap scan report for example.org (192.168.1.102)
Host is up (0.0017s latency).
Not shown: 9997 closed ports
PORT     STATE SERVICE     VERSION
22/tcp   open  ssh     OpenSSH 6.0p1 Debian 3 (protocol 2.0)
...
80/tcp   open  http    Apache httpd 2.2.22 ((Debian))
|_http-methods: No Allow or Public header in OPTIONS response (status code 200)

...
3306/tcp open  mysql   MySQL 5.5.28-1
...
&lt;/pre&gt;
&lt;p&gt;The above excerpt from the Nmap output shows information for SSH, HTTP, and MySQL services running on 192.168.1.102. It clearly shows the name and the version of each software – OpenSSH 6.0p1, Apache httpd 2.2.22, and MySQL 5.5.28-1.&lt;/p&gt;
&lt;h3&gt;Limiting the network exposure&lt;/h3&gt;
&lt;p&gt;For each exposed service, you should decide whether it's really necessary for it to be exposed. If not, one option is to make sure the service listens only on the local loopback interface (127.0.0.1). This is a good option for the MySQL service when it serves only local requests. To do that for MySQL, edit the my.cnf file. When MySQL listens on all interfaces, the &lt;code&gt;bind-address&lt;/code&gt; directive looks like this: &lt;code&gt;bind-address = 0.0.0.0&lt;/code&gt;. To make it listen only on the local interface, change it to &lt;code&gt;bind-address = 127.0.0.1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Furthermore, MySQL lets you explicitly limit the remote hosts from which a user is allowed to connect as part of MySQL's &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/connection-access.html"&gt;connection verification&lt;/a&gt; process. Such an additional security restriction helps guard against brute-force attacks but usually does not help against remote software vulnerability exploits.&lt;/p&gt;
&lt;p&gt;You can also use a firewall to restrict access to a service. When properly configured, a firewall can allow only certain hosts to connect to a given service. An example iptables command for MySQL looks like this: &lt;code&gt;iptables -I INPUT -s 192.168.1.1 -p TCP --dport 3306 -j ACCEPT; iptables -I INPUT -p TCP --dport 3306 -j DROP&lt;/code&gt;. This sample command allows MySQL connections only from the IP address 192.168.1.1.&lt;/p&gt;
&lt;p&gt;As a last resort, you may decide to change the default port for a service. This is usually feasible for sensitive services that have to remain relatively hidden but still fully accessible from outside. This is often the case with SSH when system administrators want to have access from everywhere. You can change the SSH port to a port above the commonly scanned range (1-10000). For example, if you set the SSH daemon to listen on port 19999, it's less likely to be detected, but you will be still able to access the service from anywhere as long as you know this port. To change the SSH port, edit the directive &lt;code&gt;Port&lt;/code&gt; in the file /etc/ssh/sshd_config and restart the service. Don't forget to specify this port when connecting later with your SSH client (&lt;code&gt;ssh -p&lt;/code&gt; in Linux shell).&lt;/p&gt;
&lt;p&gt;These are the simplest ways to limit the remote connectivity and protect from external attacks. If you are interested in more advanced techniques, consider &lt;a href="http://en.wikipedia.org/wiki/Port_knocking"&gt;port knocking&lt;/a&gt; as one interesting idea and option.&lt;/p&gt;
&lt;h3&gt;Limiting the exposed information&lt;/h3&gt;
&lt;p&gt;After dealing with the SSH and MySQL services from our example, only the web service remains. It is supposed to be fully accessible for the outside world on the standard HTTP TCP port 80, and we cannot hide it under a different port nor restrict the access to it. Our only choice is to disclose as little information about it as possible.&lt;/p&gt;
&lt;p&gt;According to the above example, the Apache version is &lt;code&gt;Apache httpd 2.2.22 ((Debian))&lt;/code&gt;. This gives an attacker plenty of information – web server name, version, and even operating system. You can limit this information by changing the Apache configuration and setting the &lt;a href="http://httpd.apache.org/docs/current/mod/core.html#servertokens"&gt;server token setting&lt;/a&gt; as &lt;code&gt;ServerTokens ProductOnly&lt;/code&gt;. After this, when you run the scan again, you'll see for version only &lt;code&gt;Apache httpd&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Even with our basic Nmap example we got more information than just the version. For Apache, Nmap also showed that the OPTIONS header is allowed and there is no restriction on the &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html"&gt;http methods&lt;/a&gt; – &lt;code&gt;|_http-methods: No Allow or Public header in OPTIONS response (status code 200)&lt;/code&gt;. From a security point of view it's important to restrict the allowed HTTP methods to only the ones your site really needs and thus give attackers fewer options.&lt;/p&gt;
&lt;p&gt;For example, the TRACE HTTP method echos back user input. Clearly, this is a feature useful for debugging but not needed in a production web server. The TRACE method is used in certain attacks by allowing access to sensitive information, so it should almost always be disabled. In fact, most average web servers should support only two HTTP methods: GET and POST. To forbid the rest, use the Apache directive &lt;a href="http://httpd.apache.org/docs/2.2/mod/core.html#limitexcept"&gt;limitexcept&lt;/a&gt; like this:&lt;/p&gt;
&lt;pre&gt;    Order deny,allow
    Deny from all

&lt;/pre&gt;
&lt;p&gt;Hiding the server token and forbidding unneeded communication methods is a good start, but it's far from enough. You also need an application firewall, which offers more thorough protection. Almost all publicly accessible services have such a firewall solution available. In the case of Apache, check the article &lt;a href="http://www.openlogic.com/wazi/bid/188075/"&gt;How to protect your web server with ModSecurity&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Examine your Nmap output and proceed similarly for any publicly exposed services. You should be able to foil the usual generic untargeted attacks that randomly scan the Internet for outdated or misconfigured software.&lt;/p&gt;
&lt;h3&gt;Delving deeper into penetration testing with Nessus&lt;/h3&gt;
&lt;p&gt;Nmap is powerful and lets you do some serious penetration testing of your environment, but it's not as easy to use and complete as some more advanced vulnerability scanners. &lt;a href="http://olex.openlogic.com/packages/nessus"&gt;Nessus&lt;/a&gt;, for instance, is a commercial vulnerability scanner that allows limited free use for home users. To start using it in BackTrack you have to register for a license key first and follow a few preliminary steps as described in &lt;a href="http://www.tenable.com/blog/enabling-nessus-on-backtrack-5-the-official-guide"&gt;the official Nessus on BackTrack guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you have Nessus up and running in BackTrack, you control it from an intuitive web interface accessible at https://localhost:8834. The web interface allows you to easily configure your penetration test and generate a professional-looking report upon completion.&lt;/p&gt;
&lt;p&gt;Nessus detects more than 50,000 vulnerabilities on all exposed levels, from misconfigured services to outdated software. Once it detects a vulnerability, it reports all the related information and, most importantly, suggests a solution. This saves you time, ensures that you follow the best practices for resolving a problem, and that you comply with the highest security standards.&lt;/p&gt;
&lt;p&gt;Nessus is the most preferred penetration testing solution for enterprise users. Still, Nmap remains the Swiss Army Knife for network scanning, as it provides the fastest and simplest path to exploring your environment without binding to licenses and spending significant amounts of money.&lt;/p&gt;
&lt;p&gt;No matter what application you choose, the most important thing is to understand the concept of remote security. Don't unnecessarily expose services, nor any information that is not explicitly required. That should ensure you don't attract publicly circulating threats that may exploit zero-day vulnerabilities.&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/271899/BackTrack-and-its-tools-can-protect-your-environment-from-remote-intrusions&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/vbiPVybXpPs" height="1" width="1"/&gt;</description><dc:creator>Anatoliy Dimitrov</dc:creator><pubDate>Mon, 04 Mar 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:271899</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/271899/BackTrack-and-its-tools-can-protect-your-environment-from-remote-intrusions</feedburner:origLink></item><item><comments>http://www.openlogic.com/wazi/bid/271354/Ant-buildfiles-A-look-under-the-carapace#Comments</comments><slash:comments>0</slash:comments><title>Ant buildfiles: A look under the carapace</title><link>http://feedproxy.google.com/~r/openlogic/wazi/~3/YPYwN3Mw_zw/Ant-buildfiles-A-look-under-the-carapace</link><description>&lt;p&gt;You may already use the &lt;a href="http://olex.openlogic.com/packages/ant"&gt;Apache Ant&lt;/a&gt; Java-based build tool to build projects with a presupplied build.xml file. But what if you want to do something more complicated? Knowing how Ant works under the hood will let you make the most of its capabilities. Let's dissect an Ant buildfile and examine its components.&lt;/p&gt;
&lt;p&gt;Ant operates in a different way than other command-line build tools. Instead of using shell commands to extend your tool, you extend Ant by writing Java classes to run particular tasks – although Ant comes with a huge list of available tasks. Instead of constructing a shell command to run a particular task configuration, you configure Ant in XML files. The XML creates a tree of tasks to be executed to build particular defined targets, and each task is run by its own object. The crucial implication of this is that Ant is entirely cross-platform, unlike &lt;a href="http://olex.openlogic.com/packages/gnumake"&gt;make&lt;/a&gt; and its ilk.&lt;/p&gt;
&lt;p&gt;I'll assume that you already have Ant installed for this tutorial; if not, get it from its website or your package manager.&lt;/p&gt;
&lt;h3&gt;Basic Ant building&lt;/h3&gt;
&lt;p&gt;If you just type &lt;code&gt;ant&lt;/code&gt; on the command line in an empty directory, you'll get an error message telling you that there's no build.xml file. build.xml is the file Ant needs in order to know what it's supposed to do. Let's look at the structure of a basic buildfile:&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;project name="HelloAnt" default="compile" basedir="."&amp;gt;
  &amp;lt;property name="src.dir" value="."/&amp;gt;
  &amp;lt;property name="build.dir" value="build/"/&amp;gt;

  &amp;lt;target name="clean"&amp;gt;
     &amp;lt;echo&amp;gt;Cleaning up ${build.dir}&amp;lt;/echo&amp;gt;
     &amp;lt;delete dir="${build.dir}"/&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name="init" depends="clean"&amp;gt;
     &amp;lt;echo&amp;gt;Creating build directory ${build.dir}&amp;lt;/echo&amp;gt;
     &amp;lt;mkdir dir="${build.dir}"/&amp;gt;
  &amp;lt;/target&amp;gt;

  &amp;lt;target name="compile" depends="init"&amp;gt;
     &amp;lt;echo&amp;gt;Compiling source from ${src.dir} to ${build.dir}&amp;lt;/echo&amp;gt;
     &amp;lt;javac srcdir="${src.dir}" destdir="${build.dir}"/&amp;gt;
  &amp;lt;/target&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The root element for an Ant buildfile is &lt;code&gt;project&lt;/code&gt;: the rest of the file forms part of this element. The &lt;code&gt;project&lt;/code&gt; element itself has a name, default target, and base directory, none of which are required. The buildfile then defines source and build directory properties, which it refers to later in the file. This means that if you change your directory structure, you only need to alter one place in the file. The actual work is done by three targets: clean (which deletes the build directory), init (which recreates the build directory), and compile.&lt;/p&gt;
&lt;p&gt;Each target comprises a number of tasks. Ant has a &lt;a href="http://ant.apache.org/manual/"&gt;huge list of built-in tasks available&lt;/a&gt;, and you can define more of your own by writing a Java file, though here we're just using built-in ones. &lt;code&gt;echo&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, &lt;code&gt;mkdir&lt;/code&gt;, and &lt;code&gt;javac&lt;/code&gt; all do what you'd expect; you can check out the documentation for more information. Note that the &lt;code&gt;javac&lt;/code&gt; task will fail if the destination directory doesn't already exist, hence the need to create it in the &lt;code&gt;init&lt;/code&gt; target.&lt;/p&gt;
&lt;p&gt;You'll also notice the &lt;code&gt;depends&lt;/code&gt; attribute on two of the tasks. This sets up a chain of tasks; if you tell Ant to execute Task 1 which is dependent on Task 2, Ant will run Task 2 for you first. You can also chain multiple dependencies, as here, where &lt;code&gt;compile&lt;/code&gt; depends on &lt;code&gt;init&lt;/code&gt; which depends on &lt;code&gt;clean&lt;/code&gt;. They'll all be executed in the correct order. Tasks can also have multiple dependencies, and Ant will sort out everything for you.&lt;/p&gt;
&lt;p&gt;To test this buildfile, create a basic &lt;a href="http://introcs.cs.princeton.edu/java/11hello/HelloWorld.java.html"&gt;HelloWorld.java&lt;/a&gt; file in your base directory, then type &lt;code&gt;ant&lt;/code&gt;. Since our default target is &lt;code&gt;compile&lt;/code&gt;, it should clean, init, and compile your program.&lt;/p&gt;
&lt;h3&gt;Properties&lt;/h3&gt;
&lt;p&gt;Instead of having all the properties at the start of build.xml, you can instead keep them in a properties file. This is usually called build.properties, and ours would look like this:&lt;/p&gt;
&lt;pre&gt; 
src.dir=. 
build.dir=build
test.dir=${build.dir}/test
&lt;/pre&gt;
&lt;p&gt;As you can see, you can refer to earlier properties within the file itself. You then include this build.properties file in build.xml:&lt;/p&gt;
&lt;pre&gt;&amp;lt;project name="HelloAndroid" default="help"&amp;gt;
  &amp;lt;property file="build.properties"/&amp;gt;
  ...
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This modular structure is more maintainable when you have a significant number of properties, so it's good to get into the habit of using it.&lt;/p&gt;
&lt;p&gt;You can also override properties on the command line. Try this command (note the lack of a space between the flag and the value):&lt;/p&gt;
&lt;pre&gt;ant -Dbuild.dir=test&lt;/pre&gt;
&lt;p&gt;Your project will be rebuilt into test/. Note that in this case, the old classfiles in build/ will &lt;em&gt;not&lt;/em&gt; be deleted, because the &lt;code&gt;clean&lt;/code&gt; target will be run on test/ instead.&lt;/p&gt;
&lt;h3&gt;More on targets&lt;/h3&gt;
&lt;p&gt;Ant lets you create "hidden" targets. For example, let's add a couple of targets:&lt;/p&gt;
&lt;pre&gt;&amp;lt;project name="HelloAnt" basedir="." default="compile"&amp;gt;
  ...
  &amp;lt;property name="jar.dir" value="jar/"/&amp;gt;
  &amp;lt;property name="jar.jarfile" value="HelloAnt.jar"/&amp;gt;

  ...

  &amp;lt;target name="-jarinit"&amp;gt;   
    &amp;lt;tstamp&amp;gt;   
      &amp;lt;format property="TODAY_UK" pattern="yyyy-MM-dd_HH.mm" locale="en_GB" /&amp;gt;
    &amp;lt;/tstamp&amp;gt;   
  &amp;lt;/target&amp;gt;   

  &amp;lt;target name="jar" depends="-jarinit"   
          description="Creates the binary distribution."&amp;gt;   
    &amp;lt;mkdir dir="${jar.dir}/${TODAY_UK}" /&amp;gt;   
    &amp;lt;jar basedir="${build.dir}"   
         destfile="${jar.dir}/${TODAY_UK}/${jar.jarfile}" /&amp;gt;   
  &amp;lt;/target&amp;gt;   
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The target &lt;code&gt;-jarinit&lt;/code&gt; can't be called from the command line, which makes sense, as all it does is to set up a property, &lt;code&gt;TODAY_UK&lt;/code&gt;, which is a timestamp with a particular format. However, the target &lt;code&gt;jar&lt;/code&gt;, which can be called from the command line, depends on &lt;code&gt;-jarinit&lt;/code&gt;, which sets up the directory the jar file will be saved in. If you remove that &lt;code&gt;depends="-jarinit"&lt;/code&gt; attribute, the task will still run, but it'll use the directory ${TODAY_UK} rather than substituting in the property. (This is one property that has to stay in build.xml rather than build.properties.)&lt;/p&gt;
&lt;p&gt;In fact, &lt;code&gt;jar&lt;/code&gt; really should depend on &lt;code&gt;compile&lt;/code&gt; as well as &lt;code&gt;jarinit&lt;/code&gt;, since you can't create a jarfile from a nonexistent build directory and don't want to create one from an old build directory! Change the &lt;code&gt;depends&lt;/code&gt; property to read &lt;code&gt;depends="-jarinit,compile"&lt;/code&gt; and run &lt;code&gt;ant jar&lt;/code&gt; again. You'll see Ant run &lt;code&gt;-jarinit&lt;/code&gt;, then traverse the tree of tasks to run &lt;code&gt;clean&lt;/code&gt;, &lt;code&gt;init&lt;/code&gt;, &lt;code&gt;compile&lt;/code&gt;, and then &lt;code&gt;jar&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Help!&lt;/h3&gt;
&lt;p&gt;Now try typing &lt;code&gt;ant -projecthelp&lt;/code&gt;. You should get output like this:&lt;/p&gt;
&lt;pre&gt; 
Buildfile: /home/juliet/coding/ant/build.xml

Main targets:

 jar  Creates the binary distribution. 
Default target: compile
&lt;/pre&gt;
&lt;p&gt;Only one of our tasks shows up! This is because the &lt;code&gt;jar&lt;/code&gt; task is the only one with a &lt;code&gt;description&lt;/code&gt; property. Add descriptions to the other tasks, and try &lt;code&gt;ant -projecthelp&lt;/code&gt; again:&lt;/p&gt;
&lt;pre&gt; 
Buildfile: /Users/juliet/coding/ant/build.xml

Main targets:

 -jarinit  Creates a timestamp.
 clean     Cleans up old build directory.
 compile   Compiles source.
 init      Creates build directory.
 jar       Creates the binary distribution. 
Default target: compile
&lt;/pre&gt;
&lt;p&gt;Note that even the hidden task will show up if you give it a description.&lt;/p&gt;
&lt;p&gt;It's also good practice to create a &lt;code&gt;help&lt;/code&gt; target – something like this:&lt;/p&gt;
&lt;pre&gt;&amp;lt;target name="help" depends="usage" /&amp;gt;   

&amp;lt;target name="usage" description="Display usage information."&amp;gt;   
  &amp;lt;echo message="  Execute 'ant -projecthelp' for build file help." /&amp;gt;   
  &amp;lt;echo message="  Execute 'ant -help' for Ant help." /&amp;gt;   
&amp;lt;/target&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This shows another feature of Ant targets: You can have a "target alias," meaning a target that only invokes another target. Here, all &lt;code&gt;help&lt;/code&gt; does is invoke &lt;code&gt;usage&lt;/code&gt;. This means that the user will get help from either &lt;code&gt;ant help&lt;/code&gt; or &lt;code&gt;ant usage&lt;/code&gt;. You could also alias &lt;code&gt;build&lt;/code&gt; to &lt;code&gt;compile&lt;/code&gt;, for example. This also shows another way of using the &lt;code&gt;echo&lt;/code&gt; task.&lt;/p&gt;
&lt;p&gt;It's good practice to change your default to &lt;code&gt;help&lt;/code&gt; or to something else that doesn't do much; if you make the default be &lt;code&gt;compile&lt;/code&gt;, a user may be unhappy when Ant blows away old build files, or takes ages to run for a large project.&lt;/p&gt;
&lt;p&gt;This tutorial should give you enough information to get started editing an Ant build.xml file if you want to tweak your builds a little. Once you feel comfortable, you can also try setting up an Ant file for other tasks you do regularly; there's no need to limit yourself to Java compilation!&lt;/p&gt;
&lt;img src="http://track.hubspot.com/__ptq.gif?a=172122&amp;k=14&amp;bu=http://www.openlogic.com/wazi/&amp;r=http://www.openlogic.com/wazi/bid/271354/Ant-buildfiles-A-look-under-the-carapace&amp;bvt=rss"&gt;&lt;img src="http://feeds.feedburner.com/~r/openlogic/wazi/~4/YPYwN3Mw_zw" height="1" width="1"/&gt;</description><dc:creator>Juliet Kemp</dc:creator><pubDate>Thu, 28 Feb 2013 11:00:00 GMT</pubDate><guid isPermaLink="false">f1397696-738c-4295-afcd-943feb885714:271354</guid><feedburner:origLink>http://www.openlogic.com/wazi/bid/271354/Ant-buildfiles-A-look-under-the-carapace</feedburner:origLink></item></channel></rss>
