An Introduction to Puppet

In an environment, be it development or production, managing system settings and software bits on multiple hosts that make up a working environment is a challenge. Puppet offers features that can be used to build such environments consistently and to manage them centrally.

1. Installation

Puppet 3.2.2 is installed on Linux 6 hosts as part of this tutorial. The server and agent portions of the Puppet system will be installed separately on 2 different machines, in a Agent/Master configuration.

1.1 Prerequisites

1.1.1 Operating System

Puppet can be run on all the major operating systems from flavors of UNIX to Windows. For complete list, refer Puppet’s Supported Platforms Guide: http://docs.puppetlabs.com/guides/platforms.html.

For this tutorial, Linux 6 is used and the sample commands and dependent components used will be compatible with that platform.

1.1.2 Ruby

Check version of the Ruby installed on the host and make sure that the version of Puppet that you plan to install is compatible.

$ ruby --version
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

Ruby gets installed as a dependency when Puppet software is installed.

Refer Puppet’s Supported Platforms Guide to check the compatibility: http://docs.puppetlabs.com/guides/platforms.html

1.1.3 Facter

facter is a Ruby library and application that collects and display facts about a system such as operating system names, hardware characteristics, IP addresses, MAC addresses, and SSH keys. It gets installed as a dependency when Puppet software is installed on a machine.

Using the command line tool you can query system info such as these:

$ facter ipaddress
10.88.174.167

$ facter architecture
x86_64

For a complete list of system facts, refer http://docs.puppetlabs.com/facter/1.6/core_facts.html

1.1.4 Hiera

Hiera is a simple hierarchical database used to represent hierarchically structured info such as infrastructure configuration. It gets installed as a dependency when Puppet software is installed on a machine.

1.1 Setting up yum repository

The sample steps provided here assumes that the Puppet software is installed on some version of Linux.

To setup the yum repository with the Puppet software, you need to download it first. For example, for Linux 5 and 6, you can download corresponding rpm as below:

$ rpm -ivh http://yum.puppetlabs.com/el/5/products/i386/puppetlabs-release-5-7.noarch.rpm

$ rpm -ivh http://yum.puppetlabs.com/el/6/products/i386/puppetlabs-release-6-7.noarch.rpm

For the latest version of the rpm, and other flavors of UNIX, refer http://docs.puppetlabs.com/guides/puppetlabs_package_repositories.html

1.2 Installation

Puppet is installed in the Agent/Master configuration in this tutorial – server and agent components on separate machines.

1.2.1 Installing Server

If the yum repository is setup already by downloading the Puppet software already, it can be installed as follows:

$ sudo yum install puppet-server

This will also pull in the dependent software components such as Ruby, facter and Hiera.

$ ruby --version
ruby 1.8.7 (2011-06-30 patchlevel 352) [x86_64-linux]

$ puppet --version
3.2.2

$ facter --version
1.7.2

$ hiera --version
1.2.1

The configuration file is /etc/puppet/puppet.conf. The config file can have 3 sections: main, master and agent. The settings in main is available to both master and agent processes.

Following commands can be used to start agent and master services:

$ sudo puppet resource service puppet ensure=running enable=true
$ sudo puppet resource service puppetmaster ensure=running enable=true

The master and agent processes running on the system are:

$ service puppetmaster status
puppet (pid 31311) is running...

$ service puppet status
puppet (pid 31200) is running...

The Puppet init files are these:

$ ls /etc/init.d/puppet*
/etc/init.d/puppet /etc/init.d/puppetmaster /etc/init.d/puppetqueue

Using these init files you can start and stop the services also:

$ service puppetmaster stop

1.2.2 Installing Agent

Install agent software:

$ sudo yum install puppet

Start the agent service:

$ sudo puppet resource service puppet ensure=running enable=true

Notice: /Service[puppet]/ensure: ensure changed 'stopped' to 'running'
service { 'puppet':
ensure => 'running',
enable => 'true',
}

$ service puppet status
puppet (pid 30429) is running...

Open config file /etc/puppet/puppet.conf and under the section “main”, add name of server host:

server = [name.domain]

Restart the agent:
$ sudo service puppet stop
$ sudo service puppet start

1.2.3 Verifying Installation

On the agent host, run this command:

$ sudo puppet agent --waitforcert 60 --test

This will make agent to contact the server host and wait for cert authorization.

On the server host, check for the certs that need to be authorized:

$ sudo puppet cert --list
"agenthost.domain" (SHA256) ....

Sign the certificate:

$ sudo puppet cert --sign agenthost.domain

Notice: Signed certificate request for agenthost.domain
Notice: Removing file Puppet::SSL::CertificateRequest agenthost.domain at '/var/lib/puppet/ssl/ca/requests/agenthost.domain.pem'

The output of test command on the agent host will be similar to this after the cert will be signed:

$ sudo puppet agent --test
Info: Retrieving plugin
Info: Caching catalog for agenthost.domain
Info: Applying configuration version '1373533921'
Notice: Finished catalog run in 0.04 seconds

This means your setup is correct!

2. Managing Hosts using Puppet

2.1 Defining Modules

The primary use of Puppet is to centrally manage nodes on which Puppet agent runs. The system configuration settings and static files are setup on the agent nodes based on modules defined on the Puppet master node. Usually each module defines a system configuration setting or deployment of static files.

The modules definitions are usually under the directory /etc/puppet/modules. (It is actually set by the “modulepath” configuration item in puppet.conf) The main part of a module is the class definition in /etc/puppet/modules/[module_name]/manifests/init.pp.

For example, the sample module ntp that installs and runs NTP service on node is setup as follows:

Define class in /etc/puppet/modules/ntp/manifests/init.pp:

class ntp {
package { "ntp":
ensure => installed,
}

service { "ntpd":
ensure => running,
}
}

Another module “hosts” installs /etc/hosts on the agent nodes by distributing the static file /etc/puppet/files/hosts on the Puppet master node. The class is defined in /etc/puppet/modules/hosts/manifests/init.pp:

class hosts {
file { "/etc/hosts":
owner => root,
group => root,
mode => 775,
source => "puppet:///files/hosts",
}
}

The source mentioned in the class, puppet:///files/hosts, will be translated to /etc/puppet/files/hosts on the Puppet master node. Therefore, the file must be available under that location.

$ sudo mkdir /etc/puppet/files

Save the following content of a /etc/hosts file meant for agent nodes with suitable modifications:

$ vi /etc/puppet/files/hosts

# /etc/hosts
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4

# The following lines are desirable for IPv6 capable hosts
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6

#Puppet master node
IP.ADDRESS puppetmasternode.domain puppetmaster

Add the following section to /etc/puppet/fileserver.conf, to set the mapping and access permissions:

[files]
path /etc/puppet/files
allow *

2.2 Deploying modules

The entry point to a Puppet system that consists of the puppet master node and agent nodes (master node can be one of the agents too.) is set in the config file /etc/puppet/manifests/site.pp. The application of various modules defined on agent nodes is managed using /etc/puppet/manifests/nodes.pp:

node 'masternode.domain' {
include ntp
include hosts
}

node 'agentnode.domain' {
include hosts
}

By using this, the modules ntp and hosts will be applied on the master node, and the hosts module will be applied on the agent node. To get that done, import nodes.pp in site.pp as follows:

$ cat manifests/site.pp
import "nodes"

That’s it! Now, by running the Puppet agent on master and agent nodes, the modules can be applied:

$ sudo puppet agent --test -v
Info: Retrieving plugin
Info: Caching catalog for masternode.domain
Info: Applying configuration version '1373614149'
Notice: /Stage[main]/Hosts/File[/etc/hosts]/content:
--- /etc/hosts 2013-07-10 22:40:19.758999976 +0000
+++ /tmp/puppet-file20130712-12044-1ghmk7a-0 2013-07-12 07:33:46.377666713 +0000

... (file diff)

Info: FileBucket adding {md5}1ba29d3d02db763182fc74622c057699
Info: /Stage[main]/Hosts/File[/etc/hosts]: Filebucketed /etc/hosts to puppet with sum 1ba29d3d02db763182fc74622c057699
Notice: /Stage[main]/Hosts/File[/etc/hosts]/content: content changed '{md5}1ba29d3d02db763182fc74622c057699' to '{md5}c1124f74ed6f78bea001082aa86e4f1b'
Notice: /Stage[main]/Hosts/File[/etc/hosts]/mode: mode changed '0644' to '0775'
Notice: Finished catalog run in 0.52 seconds

$ service ntpd status
ntpd (pid 8486) is running...

2.3 Applying Changes

Puppet agents apply the changes from server based on the runinterval setting in puppet.conf. The default is 30m. Various time formats (s,m,h,d and y) can be used to specify the time.

runinterval = 30s

To test this feature, do these steps:
– Add runinterval config item in the puppet.conf file on the agent machine. Set the time to something smaller than 30m, so you can verify the application of change quickly.
– Restart puppet agent service:
sudo service puppet restart
– On the server side, make some change to the source file /etc/puppet/files/hosts and save. Monitor /etc/hosts on the agent host and see if the change is applied.

Posted in Automation, DevOps, Puppet | Tagged , , , , , | 1 Comment

Integrating apps with Twitter

Adding status to your Twitter account is so easy these days, and you might wonder what is the big deal about it. But, there could be some need to post a status or a piece of information from another application. In that case, the simple to use Twitter API come in handy; it can be used to integrate your application with Twitter in various ways: the most common being just posting a status to Twitter. For example, in the from the links aggregation site I developed, urlsreview.com, every new link published is automatically added to Twitter as a status at http://twitter.com/urlsreview.

The details of Twitter API are available at http://dev.twitter.com. Basically, you need to register your app and use that info to login into Twitter and do stuff. The API is well documented at http://apiwiki.twitter.com, with sample code.

It is extremely easy to add status to Twitter via API as it shown in the following example. Basically, the curl call must be an HTTP POST and the twitter username and password can be specified as curl options. With utility classes available for curl and shortening url, the code will look much simpler. The wrapper class for Twitter API that is defined here is only good for posting a new message; and it can be expanded to inlude all the available API’s.

Twitter.php

<?php
include_once 'CurlWrap.php';

define('TWITTER_API_STATUS_UPDATE','http://twitter.com/statuses/update.json');
define('TWITTER_USERNAME','YOUR-USER-NAME');
define('TWITTER_PASSWORD','YOUR-USER-PASSWORD');
   
class Twitter
{
   private $curl;
   
   function __construct()
   {
      $this->curl=new CurlWrap();
      $this->curl->setOption(CURLOPT_POST,true);
      $this->curl->setOption(CURLOPT_USERPWD, TWITTER_USERNAME.':'.TWITTER_PASSWORD);
   }
   
   function addStatus($msg)
   {
      $this->curl->setOption(CURLOPT_POSTFIELDS, "status=".urlencode($msg));
      $this->curl->exec(TWITTER_API_STATUS_UPDATE);
      $http_code=$this->curl->getHttpCode();
      
      return ($http_code=='200'||$http_code=='201');
   }
}

?>

add_twitter_status.php

<?php
   
include_once 'Twitter.php';
include_once 'ShortUrl.php';

//Let me post a message about one of my posts here to Twitter after shortening the url
$shorturl=new ShortUrl();
$shortblogurl=$shorturl->shortenUrl('https://smoothops.wordpress.com/2010/07/16/using-curl-to-make-rest-api-calls/');
if (!$shortblogurl) {
   print "ERROR: Problem making short url.\n";
   exit;
}

$msg="Posted an article on how to use curl in PHP. Check out $shortblogurl";

$twitter=new Twitter();
if ($twitter->addStatus($msg)) print "Status '$msg' has been added to Twitter.\n";
else "ERROR: Problem adding status '$msg' to Twitter.\n";

exit;
Posted in PHP | Leave a comment

Shortening URL Using bit.ly Web Service API

Having a shortened url would be handy sometimes, especially when you need to include that in an E-Mail message to avoid splitting the long url into multiple lines or in a Twitter status message that has the 140 character limit.

Though shortening of url can be done using the many services like tinyurl.com or bit.ly, it has to be done using their API, if the message is constructed and posted from some application. My favorite site to do that is http://bit.ly and they offer a simple API. The following simple class explains how a shortened url is obtained programmatically.

ShortUrl.php

<?php
   include_once 'CurlWrap.php';

   define('BIT_LY_USERNAME','YOUR-BIT-LY-USERNAME');
   define('BIT_LY_API_KEY','YOUR-BIT-LY-APIKEY');
   define('BIT_LY_SHORTEN_API','http://api.bit.ly/shorten?version=2.0.1');

   class ShortUrl
   {
      private $curl;

      function __construct()
      {
         $this->curl=new CurlWrap();
         $this->curl->setOption(CURLOPT_POST,false);
      }

      function shortenUrl($url)
      {
         $api_call=BIT_LY_SHORTEN_API. "&longUrl=". urlencode($url). "&login=". BIT_LY_USERNAME. "&apiKey=". BIT_LY_API_KEY. "&format=xml";

     $this->curl->exec($api_call);
         $http_code=$this->curl->getHttpCode();
     if ($http_code==200||$http_code==201) {
        $response=$this->curl->getExecResponse();
        $xml=new SimpleXmlElement($response);
        return (string)$xml->results->nodeKeyVal->shortUrl;
     }
         else return false;
      }
   }
?>

You need to open an account and obtain an apiKey to use the API. The utility class CurlWrap is described <a href=”https://smoothops.wordpress.com/2010/07/16/using-curl-to-make-rest-api-calls/”>here</a&gt;.

From a PHP script, this class can be used as in the following example:

<?php
include_once 'ShortUrl.php';

$shorturl=new ShortUrl();
print $shorturl->shortenUrl('http://www.nytimes.com/2010/07/23/opinion/23krugman.html')."\n";

?>

Execution of this script got me this: “http://nyti.ms/d9U2nC&#8221;. Looks like New York Times has a special arrangement with bit.ly 🙂

<pre style=”font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%”><code>&lt;?php
include_once ‘CurlWrap.php’;

define(‘BIT_LY_USERNAME’,’YOUR-BIT-LY-USERNAME’);
define(‘BIT_LY_API_KEY’,’YOUR-BIT-LY-APIKEY’);
define(‘BIT_LY_SHORTEN_API’,’http://api.bit.ly/shorten?version=2.0.1&#8242;);

class ShortUrl
{
private $curl;

function __construct()
{
$this-&gt;curl=new CurlWrap();
$this-&gt;curl-&gt;setOption(CURLOPT_POST,false);
}

function shortenUrl($url)
{
$api_call=BIT_LY_SHORTEN_API. &quot;&amp;longUrl=&quot;. urlencode($url). &quot;&amp;login=&quot;. BIT_LY_USERNAME. &quot;&amp;apiKey=&quot;. BIT_LY_API_KEY. &quot;&amp;format=xml&quot;;

$this-&gt;curl-&gt;exec($api_call);
$http_code=$this-&gt;curl-&gt;getHttpCode();
if ($http_code==200||$http_code==201) {
$response=$this-&gt;curl-&gt;getExecResponse();
$xml=new SimpleXmlElement($response);
return (string)$xml-&gt;results-&gt;nodeKeyVal-&gt;shortUrl;
}
else return false;
}
}
?&gt;
</code></pre>

Posted in PHP | Leave a comment

Fetching RSS Feeds

You know how to fetch url using curl now. (See Using curl to make REST API calls) And let’s look at a specific use of the curl wrapper class, in which you will learn how to fetch RSS feeds and parse for specific info you are looking for.

Let’s briefly mention about RSS specification which is the short name for Really Simple Syndication. The details can be found at http://cyber.law.harvard.edu/rss/rss.html. It is an XML based specification conforms to XML 1.0. It is a very simple XML format in which the syndicated articles are listed as <item> nodes under the element <channel> which describes the feed itself, as in the following excerpts from a New York Times feed:

<channel>
        <title>NYT &gt; Home Page</title>
        <link>http://www.nytimes.com/pages/index.html?partner=rss</link>
        <description/>
        <language>en-us</language>

        <copyright>Copyright 2010  The New York Times Company</copyright>
        <lastBuildDate>Sat, 17 Jul 2010 17:43:58 GMT </lastBuildDate>
        <item>
            <title>For BP, Rising Pressure in Oil Well Seen as a Positive Sign </title>
            <link>http://feeds.nytimes.com/click.phdo?i=7ca98bec358b81188e619bc29c3988cf</link>
            <guid isPermaLink="false">http://www.nytimes.com/2010/07/18/us/18spill.html</guid>
            <description>Officials on Saturday said that pressure readings in the well were rising steadily after the valves were closed on a cap at the well’s top.&lt;br clear=&quot;both&quot; style=&quot;clear: both;&quot;/&gt;
&lt;br clear=&quot;both&quot; style=&quot;clear: both;&quot;/&gt;
&lt;a href=&quot;http://ads.pheedo.com/click.phdo?s=7ca98bec358b81188e619bc29c3988cf&amp;p=1&quot;&gt;&lt;img alt=&quot;&quot; style=&quot;border: 0;&quot; border=&quot;0&quot; src=&quot;http://ads.pheedo.com/img.phdo?s=7ca98bec358b81188e619bc29c3988cf&amp;p=1&quot;/&gt;&lt;/a&gt;
&lt;img alt=&quot;&quot; height=&quot;0&quot; width=&quot;0&quot; border=&quot;0&quot; style=&quot;display:none&quot; src=&quot;http://segment-pixel.invitemedia.com/pixel?code=Business&amp;partnerID=167&amp;key=segment&quot;/&gt;&lt;img alt=&quot;&quot; height=&quot;0&quot; width=&quot;0&quot; border=&quot;0&quot; style=&quot;display:none&quot; src=&quot;http://pixel.quantserve.com/pixel/p-8bUhLiluj0fAw.gif?labels=pub.29518.rss.Business.18272,cat.Business.rss&quot;/&gt;</description>
            <pubDate>Sat, 17 Jul 2010 16:30:51 GMT</pubDate>
        </item>
        <item>
            <title>For Kenneth Feinberg, More Delicate Diplomacy</title>
            <link>http://feeds.nytimes.com/click.phdo?i=76e429d7108fe523c9cffe56ef0adac1</link>
            <guid isPermaLink="false">http://www.nytimes.com/2010/07/17/us/17feinberg.html</guid>
            <description>Even with a $20 billion fund from BP to compensate those harmed by the spill, Kenneth R. Feinberg is playing the salesman role.&lt;br clear=&quot;both&quot; style=&quot;clear: both;&quot;/&gt;
&lt;br clear=&quot;both&quot; style=&quot;clear: both;&quot;/&gt;
&lt;a href=&quot;http://ads.pheedo.com/click.phdo?s=76e429d7108fe523c9cffe56ef0adac1&amp;p=1&quot;&gt;&lt;img alt=&quot;&quot; style=&quot;border: 0;&quot; border=&quot;0&quot; src=&quot;http://ads.pheedo.com/img.phdo?s=76e429d7108fe523c9cffe56ef0adac1&amp;p=1&quot;/&gt;&lt;/a&gt;
&lt;img alt=&quot;&quot; height=&quot;0&quot; width=&quot;0&quot; border=&quot;0&quot; style=&quot;display:none&quot; src=&quot;http://segment-pixel.invitemedia.com/pixel?code=Business&amp;partnerID=167&amp;key=segment&quot;/&gt;&lt;img alt=&quot;&quot; height=&quot;0&quot; width=&quot;0&quot; border=&quot;0&quot; style=&quot;display:none&quot; src=&quot;http://pixel.quantserve.com/pixel/p-8bUhLiluj0fAw.gif?labels=pub.29518.rss.Business.18272,cat.Business.rss&quot;/&gt;</description>
            <pubDate>Sat, 17 Jul 2010 16:10:23 GMT</pubDate>
        </item>
</channel>

Though you will find lot more sub-nodes under <item> element for other attributes of an article, an RSS feed requires to have only 3 attributes: title,link and description that are specified in the corresponding nodes. Therefore, a generic class that would try to parse details of articles listed in an RSS feed can reliably look only for those attributes.

The RssFeed class just does that: returns list of articles in an array for the RSS feed provided as input. The hash it uses to store article attributes contains pubDate also, as that is a common optional attribute most every RSS feed seems to include. For specific requirements, this class can be modified to include other attributes.

<?php
include_once 'CurlWrap.php';

class RssFeed
{
   private $feed_url;
   private $curl;
   private $items=array();

   function __construct($url='')
   {
      $this->curl=new CurlWrap();
      if ($url!='') {
         $this->feed_url=$url;
         $this->loadItems();
      }
   }

   function setFeedUrl($url) {$this->feed_url=$url; }

   function loadItems()
   {
      $this->curl->exec($this->feed_url);
      if ($this->curl->getHttpCode()==200) {
         $rss=new SimpleXmlElement($this->curl->getExecResponse());
         $items=$rss->channel->item;
         foreach ($items as $item) {
            $title=(string)$item->title;
            $link=(string)$item->link;
            $description=(string)$item->description;
            $pub_date=(string)$item->pubDate;
            $item_hash = array (
                'title'=>$title,
                'link'=>$link,
                'description'=>$description,
                'pubDate'=>$pub_date
            );
            $this->items[]=$item_hash;
         }
      }
   }

   function getItems() {return $this->items; }
}
?>

The sample program simply prints the article links and related titles.

<?php
include_once 'RssFeed.php';

$feed=new RssFeed("http://www.nytimes.com/services/xml/rss/nyt/pop_top.xml");
foreach ($feed->getItems() as $item) {
   print "link: ". $item['link']. "\n";
   print "title: ". $item['title']. "\n";
}
?>

Multiple feeds can be parsed by simply changing the feed url (setFeedUrl) and reloading the article items (loadItems).

Posted in PHP | Leave a comment

Using curl to make REST API calls

My preferred method to make REST calls from PHP is using curl; a REST GET call is nothing more than just fetching a file sitting on a web server. PHP supports it as long as the libcurl package is installed on your system and PHP is compiled with the curl option.

The following curl wrapper class is to make our life little easier when making calls to REST API. You can use curl functions directly, but I found the code to be verbose with all the error handling and status checks that go with each call, which can overwhelm someone reading the code, including you when you come back to your code to make some change or fix something.

CurlWrap.php

<?php

   define('CURL_EXEC_RETRY_MAX',3);

   class CurlWrap
   {
      private $ch;
      private $url;
      private $response;
      private $info;
      private $http_code;

      function __construct()
      {
         $this->ch = curl_init();
         $this->setOption(CURLOPT_RETURNTRANSFER,true);
         $this->setOption(CURLOPT_BINARYTRANSFER,true);
         $this->setOption(CURLOPT_FOLLOWLOCATION,true);
      }

      function __destruct() {curl_close($this->ch); }

      public function setOption($option,$value) {curl_setopt($this->ch,$option,$value);}

      public function exec($url='')
      {
         if ($url!='') $this->setOption(CURLOPT_URL,$url);
         $this->retryExec();
         $this->info=curl_getinfo($this->ch);
         $this->http_code=$this->info['http_code'];
      }

      public function getHttpCode() {return $this->http_code;}
      public function getExecResponse() {return $this->response;}
      public function getExecInfo() {return $this->info;}
      public function getError() {return curl_error($this->ch);}

      //The logic of retry can be different, but when making a web service call
      //it is essential have some retry, as the resource might not be accessible briefly online
      //due to many reasons.
      private function retryExec()
      {
         $i=0;
         while ($i++ <CURL_EXEC_RETRY_MAX) {
            $this->response=curl_exec($this->ch);
            if ($this->response) break;
            if ($i<CURL_EXEC_RETRY_MAX) sleep($i);
         }
      }

   }
?>

Using CurlWrapper class

Using this class making curl calls from your PHP code would be very easy. Look at this sample program, which fetches the RSS feed for the most E-Mailed articles.

test_curlwrap.php

<?php

include_once 'CurlWrap.php';

$curl=new CurlWrap();
$curl->exec("http://www.nytimes.com/services/xml/rss/nyt/pop_top.xml");
if ($curl->getHttpCode()!='200')  print "ERROR: Failed to fetch url. ". $curl->getError(). "\n";
else print $curl->getExecResponse();

?>

This will just print out the RSS feed.

Now, try changing the domain to something non-existent, like http://www.xxnytimes.com. Then you will see an error message like this:
ERROR: Failed to fetch url. Couldn’t resolve host ‘www.xxnytimes.com’

The default HTTP request method used by curl is GET, and that’s what we used in the last example. REST API’s typically use GET for reads, POST for creating a new entry, and PUT for updating an existing entry. In such cases, related options must be set prior to making call to the API. We will learn such things in later posts where I will describe how your PHP app can be integrated with Twitter.

Posted in PHP | 6 Comments

Operator And The Art of System Maintenance

I attempted to read philosophy books, especially the works of Nietzsche,  many times and gave up soon in all the occasions as  I found it hard to follow the subject matter. But, Robert M. Pirsig’s Zen And The Art of Motorcycle Maintenance was a huge exception. It read like a novel, sounded very rational and touched  me: the picture of the father-son duo’s trip from east to west on a motorcycle is something permanently installed in my mind. Especially the tragic end of the kid in San Francisco few years after their trip which is the main thread of the book.

But, what that has to do with a technology blog, in which I plan to write about few useful things that might make you a smooth operator? Well, there is something profoundly monotonous about an operator- be it a data center operator or any other operator who runs something, or even somebody who builds something mechanically without thinking much about what he is doing. Whole idea of this blog is to avoid getting into such a situation and make your work interesting and thus the importance of becoming a smooth operator; I couldn’t resist using the rather common phrase “smooth operator” in place of more relevant phrase “smart operator”.

The humble philosophical foundation of this blog is a small excerpt from Zen And The Art of Motorcycle Maintenance:

(The author provides a block diagram of components and assemblies of a motorcycle.)

The box “motorcycle” contains the boxes “components” and “functions”. The box “components” contains the boxes “power assembly” and “running assembly”, and so on. There are many kinds of structures produced by other operators such as “causes” which produce long chain structures of the form, “A causes B which causes C which causes D,” and so on. A functional description of the motorcycle uses this structure. The operators “exists”, “equals”, and “implies” produce still other structures. These structures are normally interrelated in patterns and paths so complex and enormous no one person can understand more than a small part of them in his lifetime. The overall name of this interrelated structures, the genus of which the hierarchy of containment and structure of causation are just species, is system. The motorcycle is a system. A real system.

The true system, the real system, is our present construction of systematic thought itself, rationality itself, and if a factory is torn down but the rationality which produced it is left standing, then that rationality will simply produce another factory.

My response is: Ruby on Rails or Perl/CGI used for building it, the elegance of a software system lies in your rational thinking. Rest of the thinking is left to whoever made it up until here 🙂

Posted in Philosophy | Leave a comment

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!

Posted in Uncategorized | 1 Comment