<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Connecting the dots... &#187; Web Development</title>
	<atom:link href="http://blog.rajatpandit.com/category/web-development/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.rajatpandit.com</link>
	<description>Thoughts on Web Development, Infrastructure and Application Scalability</description>
	<lastBuildDate>Thu, 29 Dec 2011 13:21:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Notes on Git Part I / Quickstart Guide to Git</title>
		<link>http://blog.rajatpandit.com/2011/12/27/notes-on-git-part-i-quickstart-guide-to-git/</link>
		<comments>http://blog.rajatpandit.com/2011/12/27/notes-on-git-part-i-quickstart-guide-to-git/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 12:25:46 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=753</guid>
		<description><![CDATA[Git stores all the information locally, commit logs, versions etc so there is very little you can&#8217;t do if you are offline everything is check summed before it enters the...]]></description>
			<content:encoded><![CDATA[<ul>
<li>Git stores all the information locally, commit logs, versions etc so there is very little you can&#8217;t do if you are offline</li>
<li>everything is check summed before it enters the repo, it uses SHA-1 hash which is a 40 character string composed  of hex and calculated based on a file or directory structure in Git.</li>
<li>files have three states
<ul>
<li>committed: data is safely stored in the local database</li>
<li>modified: the file is modified but not committed</li>
<li>staged: marked a file in its current version to go into your next commit snapshot.</li>
</ul>
</li>
<li>Three main sections of a git project
<ul>
<li>working directory: single check-out of one version of the project</li>
<li>staging area: is a simple file that stores information of what will go in the next commit. its referred to an index </li>
<li>git directory (repo) where all the metadata and the object database for your project is stored.</li>
</ul>
</li>
<li>define your git identity:
<pre class="brush: plain; title: ; notranslate">
$ git config --global user.name 'Rajat Pandit'
$ git config --global user.email 'rajat@virajsolutions.com'
</pre>
</li>
<li>define the editor
<pre class="brush: plain; title: ; notranslate">
$ git config --global core.editor vim
$ git config --global merge.tool vimdiff
</pre>
</li>
<li>checking the settings <code>$ git config --list</code>
</li>
<li>Initialize a git repo.<code>$ git init </code></li>
<li>add files to the repo<code>$ git add *.</code></li>
<li>commit message:<code>$ git commit -m '<your message goes here>';</code></li>
<li>cloning a repo: this is not the same as svn&#8217;s checkout. every version of every file is brought down. infect if the server crashes, any of the cloned copies can be used to bring the server back to the state in was in when it was cloned.
<li>$ git clone git://bla.com/morebla.git mybladir</li>
</li>
<li>git has a number of transfer protocols
<ul>
<li>git://</li>
<li>http(s)://</li>
<li>user@server:/path.git (ssh protocol)</li>
</ul
</li>
<li>files are either
<ul>
<li>tracked: (modified, unmodified or staged)</li>
<li>untracked: (any files in the working directory which are not present in the last snapshot and not in your staging area)</li>
</ul>
</li>
<li>checking the status of files<code>$ git status</code></li>
<li>revert a file change<code>$ git reset HEAD <file> # to upstage the command</code></li>
<li>if you do a <code>"git add"</code> and the modify the file and commit it the changes at the point of last <code>'git add'</code> will get committed. if the new changes need to be added as well the file has to be <code>'git add''ed </code>again&#8217;</li>
<li>defining ignore files by adding them to the .gitignore files. The following rules for the pattern work
<ul>
<li>blank lines or lines starting with # are ignored</li>
<li>standard glob patters work</li>
<li>patterns can be ended with a / to specify a directory</li>
<li>you can negate a pattern by starting it with a !</li>
</ul>
</li>
<li>to see what will go in the next commit:
<pre class="brush: plain; title: ; notranslate">
$ git diff --staged
$ git diff (will only show untagged changes)
$ git diff --staged (will show the diff for the staged files)
</pre>
</li>
<li>to remove a file<code>$ git rm <filename></code>It removes it from the staging area and also physically moves to file to ensure that it doesn&#8217;t appear as a tracked file.</li>
<li>To remove a file from staging area but not form the file system.<code>$ git rm --cached readme.txt</code>
<p>This is useful particularly in case where you possibly forgot to add it in the .gitignore file and it got pushed to the staging area and then had to be taken out but not removed from the filesystem.
</li>
<li>To use the glob patterns, stuff needs to be escaped.
<pre class="brush: plain; title: ; notranslate">
$ git rm log/\*.log
$ git rm \*~
</pre>
</li>
<li>moving files around:<code>$ git mv file_from file_to</code></li>
<li>git status will show this as a file renamed. its the equivalent of renaming the file first, git rm the first file and then git add the new one</li>
<li>git has no meta data that tells you later that you had renamed the file. </li>
<li> viewing history using git log
<pre class="brush: plain; title: ; notranslate">
$ git log -p -2
-p shows the diff
-2 limits the entries to 2 by default shows the most recent commit first.
$ git log --stat
--stat shows the abbreviated stats for all the changes that happened
$ git log --stat --pretty=&lt;online|full|fuller&gt;
$ git log --stat --pretty=format:&quot;%h - %an, %ar : %s&quot;
(ref: http://progit.org/book/ch2-4.html)

$ git log --pretty=format:&quot;%h %s&quot; --graph

(adds a nice little ASCII graph showing your branch and merge history)
$ git log --since=2.weeks
$ git log --author=&lt;name of author&gt; --grep=&quot;search in commit messages&quot; to make both of them count you also need to pass --all-match option
</pre>
</li>
<li>git understands the difference between author and patcher.
<ul>
<li>author: who created originally wrote the work</li>
<li>committer: who applied the last of the work.</li>
</ul>
</li>
<li>Amend a commit, in case you forgot to put a file in stage then you can put it as a second step:
<pre class="brush: plain; title: ; notranslate">
$ git commit -m 'intial commit'
$ git add forgotten_file
$ git commit --amend
</pre>
</li>
<li>in case you have staged two files but want them to be committed in separate commits, how do you &#8216;upstage&#8217; your files.
<pre class="brush: plain; title: ; notranslate">
	$ git add * # staged all the changes
	$ git reset HEAD benchmarks.rb # keeps the file modified but takes it out of the staging area
</pre>
</li>
<li>reverting local modification <code>$ git checkout -- benchmarks.rb</code></li>
<li>get the info about the remote git repo. if you have more than one remote repo then the command lists all of them
<pre class="brush: plain; title: ; notranslate">
$ git remote -v
</pre>
</li>
<li>adding a remote repo
<pre class="brush: plain; title: ; notranslate">
$ git remote add [shortname] [url]
$ git remote add pb git://github.com/paulboone/ticgit.git
</pre>
</li>
<li>now you can fetch all the changes in pb that are not in origin<br />
	<code>$ git fetch pb </code><br />
	this will check out the changes in pb/master you can then merge it in to one of your branches or checkout a local branch at this  point if you want to inspect it.
</li>
<li>update your current code from the remote repo <code>$ git pull # automatically pulls from the origin)</code>
</li>
<li>pushing changes to the report server
<pre class="brush: plain; title: ; notranslate">
$ git push [remote-name] [branch-name]
$ git push origin master
</pre>
<p><b>note:</b> push will only work only if no one else has pushed their changes, if that&#8217;s the case, your push will be rejected and you will have to pull to bring your code to the most recent state.
</li>
<li>inspecting a remote <code>$ git remote show [remote-name]</code><br />
	shows the branches on the remote and also the branch the pull is associated with.
</li>
<li>git tagging <code>$ git tag # list the number of tags n your code</code></li>
<li>git uses two main types of tags: <code>lightweight</code> and <code>annotated</code>. A lightweight tag is very much like a branch that doesn&#8217;t change &#8211; its just a pointer to a specific commit. Annotated tags, however are stored as full objects in the git database.The annotated tags are checksummed, contain a tagger name, email and date; have a tagging message and can be signed and verified with GNU privacy Guard. its generally recommended that you create annotated tags so that you can have all this information; but if you want a temporary tag or for some reason don&#8217;t want to keep the other information then keep the other information, lightweight tags are also available.</li>
<li>create and show new annotated tag
<pre class="brush: plain; title: ; notranslate">
$ git tag -a v1.0 -m 'bla bla bla bla'
$ git show v1.0
$ git tag # lists all the tags on the code also create a signed tag
$ git tag -s v1.5 -m 'my super signed tag'
</pre>
</li>
<li>creating a light weight:
<pre class="brush: plain; title: ; notranslate">
$ git tag v1.4
$ git tag
lists all the tag along with annotated, signed or lightweight tags
$ git show v1.4
* verifying a signed tag:
$ git tag -v v1..4
</pre>
<p>	you require to have the public key installed to verify that the tag is from the right author
</li>
<li>you can also tag later by specifying commit checksum or part of it.<code>$ git tag -a v1.2 9fceb02</code>
</li>
<li>sharing tags, by default the tags are not transferred to the remote server when using git push,they have to be explicity pushed though<br />
	<code>$ git push origin [tagname]</code><br />
	if you have lots of tags and want to push all of them at the same time.<br />
	<code>$ git push origin --tags</code>
</li>
</ul>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/27/notes-on-git-part-i-quickstart-guide-to-git/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes on VirtualBox / Quickstart guide to VirtualBox</title>
		<link>http://blog.rajatpandit.com/2011/12/23/notes-on-virtualbox-quickstart-guide-to-virtualbox/</link>
		<comments>http://blog.rajatpandit.com/2011/12/23/notes-on-virtualbox-quickstart-guide-to-virtualbox/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 14:32:04 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=745</guid>
		<description><![CDATA[General Notes &#8220;hosted&#8221; hypervisor or type 2 hypervisor where as a &#8220;bare-metal&#8221; or &#8220;type 1&#8243; hypervisor would run directly on the hardware open virtualization format (OVF) VirtualBox Remote Desktop Extension...]]></description>
			<content:encoded><![CDATA[<h3>General Notes</h3>
<ul>
<li>&#8220;hosted&#8221; hypervisor or type 2 hypervisor where as a &#8220;bare-metal&#8221; or &#8220;type 1&#8243; hypervisor would run directly on the hardware</li>
<li>open virtualization format (OVF)</li>
<li>VirtualBox Remote Desktop Extension (VRDE) &#8211; also support for full client USB Support</li>
<li>Extensible RDP authentication</li>
<li>USB Over RDP</li>
<li>Extension packs available
<ul>
<li>the virtual USB 2.0 (EHCI) device</li>
<li>virtual boc remote desktop protocol</li>
<li>Intel PXE boot RPM with support for E1000 network card</li>
</ul>
</li>
<li>fixed sized hard disk image is faster and has less overheads compared to an expanding overhead</li>
<li>different kinds of disks:
<ul>
<li>VDI</li>
<li>VMDK</li>
<li>VHD</li>
<li>HDD</li>
</ul>
</li>
<li>Two importable formats:
<ul>
<li>VMDK with a file in an XML Dialect with an .ovf extension. These files must reside in the same directory for the VirtualBox to be able to import them.</li>
<li>Everything in a single archive called the .ova extension. its an archive file with a variant of the TAR archive format)</li>
</ul>
</li>
<li>Commmands in the virtualbox package
<ul>
<li>VirtualBox &#8211; virtualbox manager</li>
<li>VBoxManage is a command line manager fro very detailed control</li>
<li>VBoxSDL for simple graphical frontend</li>
<li>VBoxHeadLess is yet another frontend to produce no visible output on the host at all.</li>
</ul>
</li>
<li>Dynamic Kernal Module Support requires to be installed, this framework helps with building and upgrading kernel modules.</li>
<li>if the kernel of your linux host was updated and DKMS is not installed, in that case the kernel module will need to be reinstalled by executing (as root)
<pre class="brush: plain; title: ; notranslate">
$ /etc/init.d/vboxdrv setup
</pre>
</li>
<li>virtualbox now not only supports PIIX3 but also the ICH9 chipset for latest operating systems like macosx</li>
<li>Auto mounting: linux guests automounted shared folders are mounted into /media directory align with the prefix sf_. for example, the shared folder mayflies would be mounted to <code>/media/sf_myfiles</code> on linux. The sf_ is controlled by the property <code>/VirtualBox/GuestAdd/SharedFolders/MountPrefix</code> </li>
<li>access to the automounted folders is only granted to members of the user vboxsf</li>
<li>listing the virtualbox guest property
<pre class="brush: plain; title: ; notranslate">$ VBoxManage guestproperty enumerate &quot;Windows Vista&quot; </pre>
<p>or listing a specific property</p>
<pre class="brush: plain; title: ; notranslate">$VBoxManage guestproperty get &quot;windows vita&quot; &quot;/VirtualBox/GuestInfo/OS/Product&quot;</pre>
</li>
<li>to change values use <code>$ VBoxControl guestproperty enumerate</code></li>
<li>VBoxManage guest-control to run commands inside the guest from the host machine</li>
<li>Memory ballooning is used to share memory associated with a vm with another vm. This is used for memory over commitment. </li>
<li>VBoxManage controlvm &#8220;VM Name? guestmemoryballoon <n> where n is the memory  the memory to allocate the guest vm. the guest additions software must be installed for this to run.</li>
<li>Virtual box dedups the page duplication by using PageFusion you can only turn it on when a vm is turned off</li>
<li><code>VBoxManage modifyvm "VM Name" --pagefusion</code> on<br />
you can observe page fusion operation using metrics RAM/VMM/Shared shows the total amount of fused pages, whereas the per-vm metric guest/RAM/Usage/Shared will return the amount of fused memory for a given VM.</li>
<li>Virtualbox allows you to manage the size of the disk even after the disk creation, even after data has been written to  it.</li>
<li>Virtualbox disk format:
<ul>
<li>normally by default for a new image, the format it uses is called Virtual Disk Image (VDI). </li>
<li>VirtualBox also fully supports the popular and open VMDK contrainer format that is used by many popular virtualization softwares like VMWare.</li>
<li>Alsofully supports the VHD format from microsoft.</li>
<li>Image files from Parallers version 2 (HDD format) also supported. newer formats 3, and 4 are not supported however you can convert them into older format (version 2) by using tools provided by parallels.</li>
</ul>
</li>
<li>Do not simply make copies of virtual disk images. if you import such a second copy into a virtual machine, virtualbox will complain with an error, since VirtualBox assigns a unique identifier (UUID) to each disk image to make sure it is only used once. </li>
<li>
Disk modes:</p>
<ul>
<li>normal mode, allows you to take snapshots and restore from it.</li>
<li>write-through hard disks: are completely unaffected by snapshots. their states are not taken and not restores when snapshots are restored.</li>
<li>shareable hard disks: works the same as write-though hard disks however they can be used to be shared across multiple VMS writing to it directly. standard filesystem is not setup to be written by multiple file systems at the same time.only fixed size images can be used in this way, and dynamically growing images are rejected.</li>
<li>immutable images only remember write access temporarily while virtual machines are running. so the approach is create a new &#8216;normal&#8217; image and once you are happy with the setup and deem its contents useful then mark it &#8216;immutable&#8217;;</li>
<li>if you take a snapshot of a machine with immutable images, then on every machine power-up those images are reset to the state of the last (current) snapshot (instead of the state of the original immutable image)</li>
<li>As a result the same immutable image can be used by several virtual machines without restrictions. (Also looking at the &#8216;enabling the differencing disks&#8217; that with auto-reset turned to off so that the vm&#8217;s sharing the immutable disk don&#8217;t forget the settings.</li>
</ul>
</li>
<li>An image in &#8216;multi-attach mode&#8217; an be attached to more than one virtual machine at the same time, even if these machines are running simultaneously. For each virtual m aching to which an image is attached, a differencing image is c reared. As a result data that is written to such a virtual disk by one machine is not seen by the other machines to which the image is attached. each machine creates its own  history of the multi-attach image. </li>
<li>The standard approach would be &#8216;one immutable disk for the operating system&#8217; and one &#8216;write-though&#8217; for your data files. </li>
<li>Networking: virtualbox providers up to eight virtual PCI ethernet cards for each virtual machine. for each such card, you can individually select:
<ul>
<li>The hardware that will be virtualised as well as</li>
<li>The virtualization mode that the virtual card will be operating in with respect to your physical networking hardware on the host.</li>
</ul>
</li>
<li>
Networking modes:</p>
<ul>
<li>Not attached: in this mode the virtualbox reports to the guest that a network card is present but there is no connection, as if no ethernet cable was plugged into the card.
<li>NAT: default mode, only required to browse the web, download files and view email inside the guests. certain limitations when windows file sharing. </li>
<li>Bridged network: more advanced needs such as network simulations and running servers in a guest. when enabled virtual box connects to on our installed network cards and exchanges network packets directly, circumventing your host operating system&#8217;s network stack.</li>
<li>Internal networking: visible to only certain software based networking (selected virtual machine) but not to applications running on the host or the outside world. Internal networking is the same as bridged networking as that it lets the vm speak to the outside world except that the outside world is the other vm&#8217;s on the same host.</li>
<li>Host-only networking: create a networking containing the host and a set of virtual machines without the need of the host&#8217;s physical network interface. instead a virtual network interface (similar to loopback interface) is created on the host, providing connectivity among virtual machines and the host.</li>
<li>VDE (virtual distributed ethernet) networking: </li>
</ul>
</li>
<li>port forwarding
<pre class="brush: plain; title: ; notranslate">
VBoxManage modifyvm &quot;VM name&quot; --natpf1 &quot;guestssh,tcp,,2222,,22&quot;
natpf1 denotes the network card
2222 is the port on the host
22 is the port on the guest
guestssh is purely description and will be auto-generated if not present
</pre>
</li>
<li>to remove the same rule:<br />
<code>VBoxManage modifyvm "VM name" --natpf1 delete "guestssh"</code></p>
<p>NOTE: it is not possible to configure incoming NAT connections while the VM is running. However, you can change the settings for a VM which is currently saved (or powered off at a snapshot)
</li>
<li>bridged networking: with bridged networking, virtualbox uses a device driver on your host system that filters data from your physical network adapter. this driver is therefore called &#8216;net filter&#8217; driver. this allows virtualbox to intercept data from the physical network and inject data into it, effectively creating a new network interface in software. When a guest is using such a new software interface, it looks to the host system to the host system as though the guest were physically connected to the interface using a network cable. the host can send data to the guest though that interface and receive data from it. thismeans that yo can setup routing and bridging between the guest and the rest of your network.</li>
<li>running virtualbox as headless
<pre class="brush: plain; title: ; notranslate">VBoxManage startvm &quot;VM Name&quot; --type headless</pre>
<p>the extra &#8211;type option causes VirtualBox to use VBoxHeadless as the front-end to the internal virtualization engine instead of the qt-front-end<br />
the alternate syntax is:</p>
<pre class="brush: plain; title: ; notranslate">VBoxHeadless --startvm &lt;uuid|name&gt;</pre>
</li>
</ul>
<h2>Steps to install a vm headless server</h2>
<p>create a new virtual machine</p>
<pre class="brush: plain; title: ; notranslate">
VBoxManage creative --name &quot;Windows XP&quot; --ostype WindowsXP --register

--registervm is optional, doing it now saves you from having to do that manually later.
--ostype is also optional but selecting this upfront results in some default options to be selected.
[/cpde]

To get the complete list

&lt;code&gt;VBoxManage list ostypes&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;make sure that the vm is configured the guest operating system.
	1VBoxManage modifyvm &quot;Windows XP&quot; --memory 256 --acpi on --boot1 dvd --nic1 nat</pre>
</li>
<li>Create a virtual hard disk for the vm (10GB)
<pre class="brush: plain; title: ; notranslate">VBoxManage createhd --filename &quot;WinXP.vdi&quot; --size 10000</pre>
</li>
<li>Add an IDE controller to the new VM
<pre class="brush: plain; title: ; notranslate">VBoxManage storagectl &quot;Windows XP&quot; --name &quot;IDE Controller&quot; --add ide --controller PIIX4</pre>
</li>
<li>set the VDI created above as the first virtual disk of the new VM
<pre class="brush: plain; title: ; notranslate">VBoxManage storageattach &quot;Windows XP&quot; --storagectl &quot;IDE Controller&quot; --port 0 --device 0 --type hdd --medium &quot;WinXP.vdi&quot;</pre>
</li>
<li>attach the ISO file that contains the operating system
<pre class="brush: plain; title: ; notranslate">VBoxManage storageattach &quot;Windows XP&quot; --storagectl &quot;IDE Controller&quot; --port 0 --device 1 </pre>
</li>
<li>type
<pre class="brush: plain; title: ; notranslate">dvddrive --medium /full/path/to/iso.iso</pre>
</li>
<li>Start the virtual machine
<pre class="brush: plain; title: ; notranslate">VBoxHeadless --startvm &quot;Windows XP&quot;</pre>
</li>
</ul>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/23/notes-on-virtualbox-quickstart-guide-to-virtualbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Notes on MongoDB / Quickstart Guide to MongoDB</title>
		<link>http://blog.rajatpandit.com/2011/12/23/notes-on-mongodb-quickstart-guide-to-mongodb/</link>
		<comments>http://blog.rajatpandit.com/2011/12/23/notes-on-mongodb-quickstart-guide-to-mongodb/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 11:56:00 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[document store]]></category>
		<category><![CDATA[mongodb]]></category>
		<category><![CDATA[NOSQL]]></category>
		<category><![CDATA[schema-less]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=737</guid>
		<description><![CDATA[large system (multi-shards, config servers and mongo routers) data model database holds collections collection holds documents document is a set of fields field is a key-value pair key is a...]]></description>
			<content:encoded><![CDATA[<ul>
<li>large system (multi-shards, config servers and mongo routers)</li>
<li>data  model
<ul>
<li>database holds collections</li>
<li>collection holds documents</li>
<li>document is a set of fields</li>
<li>field is a key-value pair</li>
<li>key is a name</li>
<li>value is:
<ul>
<li>basic type </li>
<li>a document</li>
<li>or an array of values</li>
</ul>
</li>
</ul>
</li>
<li>mongo query language</li>
<li>BSON is a binary encoded serialization of JSON like documents. BSON was designed to be lightweight, traversable and efficient. BSON like JSON supports embedding of objects and arrays within other objects and arrays.</li>
<li>MongoDB uses BSON as a data storage and network transfer format for &#8220;documents&#8221;
<pre class="brush: plain; title: ; notranslate">
$bson = bson_encode(null);
$bson = bson_encode(array('a' =&gt; 10));
</pre>
</li>
<li>using a database
<pre class="brush: plain; title: ; notranslate">
	&gt; use mydb
</pre>
<p>	switched to db mydb
</li>
<li>Insert data inside a collection
<pre class="brush: plain; title: ; notranslate">
	&gt; j = {name: 'mongo'}
	&gt; db.things.save(j);
	&gt; db.things.find();
</pre>
</li>
<li>no collection was predefined, it appeared lazily	</li>
<li>no structure for the document to store</li>
<li>mongo addeds an objectID in the field _id</li>
<li>do stuff in a loop
<pre class="brush: plain; title: ; notranslate">
	&gt; for(var i=1;i&lt;=20;i++) db.things.save({x:4, j:i});
	&gt; db.things.find();
</pre>
</li>
<li>find returns back a cursor, navigation between results is possible using the &#8216;it&#8217; command
<pre class="brush: plain; title: ; notranslate">
c = db.things.find();
	&gt; while (c.hasNext()) printjson(c.next());
	&gt; db.things.find().foreach(printjson);
</pre>
</li>
<li>
<pre class="brush: plain; title: ; notranslate">
  &gt; var c = db.things.find()
  &gt; printjson(c[4]);
</pre>
<p>will show the 5th record, not right because it will load all the results unto 4 in the memory which can have scalability issues
</li>
<li>
<pre class="brush: plain; title: ; notranslate">
&gt; db.things.find().toArray();
</pre>
</li>
<li>more queries
<pre class="brush: plain; title: ; notranslate">
select * from things where name = &quot;mongo&quot;
&gt; db.things.find({name: 'mongo'}).forEach(printjson);
select * from things where x = 4;
&gt; db.things.find({x:4}).forEach(printjson);
NOTE: that the _id field is always returned
</pre>
</li>
<li>allows returning only partial documents as well. for exam for name: &#8216;rajat&#8217; return only the key j
<pre class="brush: plain; title: ; notranslate">
	db.things.find({x:4}), {j:true}.foreach(printjson);
&gt; findOne() - syntactic sugar
	&gt;printjson(db.things.findOne({name: 'mongo'});
this is the same as
	&gt;find({name: 'mongo'}).limit(1);
&gt;printjson
function(x) {
	print(tojson(x));
}
</pre>
</li>
<li>mongo is full javascript shell, so any javascript function, syntax or class  can be used in the shell.besides it defines some of its own globals like (b etc). you can see the full api at. <a href="http://api.mongodb.org/js/">http://api.mongodb.org/js/</a></li>
<li>
<pre class="brush: plain; title: ; notranslate">
select * from users where age=33 order by name
db.users.find({age: 33}).sort({name: true});

select * from users where age&gt;33
db.users.find({'age': {$gt: 33}})
or $lt

select * from users where name like '%joe%';
db.users.find({name:/Joe/});
&quot;Joe%&quot; = {name:/^Joe/};
$lt = less than , $lte = less than equal to

sort order desc = .sort({name: -1});

create index myindexname on users(name);
db.users.ensureIndex({name: true});

create index myindex on users(name, ts desc)
db.users.ensureIndex({name:1, ts:-1});

select * from users where a=1 or b = 2
db.users.find({$or: [{a:1}, {b:2}]});

explain select * from users where z=2;
db.users.find({z:2}).explain();

select distinct last_name from users;
db.users.disctinct('last_name');

select count(*) from users;
db.users.count();

select count(age) from users;
db.users.find(age: {$exists: true}).count();
</pre>
</li>
<li>Commands:<br />
the mongo db has a concept of a database command as a way to perform special operations, or to request information about its current operational status.<br />
A command is sent to the database as a query to a special collection namespace called $cmd. The database will return a single document with the command results &#8211; user findOne(0 for that if your driver has it.<br />
the general syntax is:</p>
<pre class="brush: plain; title: ; notranslate">
db.$cmd.findOne({&lt;commandname&gt;: &lt;value&gt;[, options]});
the shell provides a helper function for this:
db.runCommand({&lt;commandname&gt;: &lt;value&gt;[, options]);
</pre>
<p>for example to check our database current&#8217; profile level eating<br />
privileged commands:</p>
<pre class="brush: plain; title: ; notranslate">
&gt; use admin
&gt; db.runCommand('shutdown');
</pre>
<p>getting help info for a command</p>
<pre class="brush: plain; title: ; notranslate">
&gt; db.commandHelp('datasize');
</pre>
</li>
<li>Clone Database
<pre class="brush: plain; title: ; notranslate">
// copy the entire database from one name to one server
db.copyDatabase(&lt;from-db&gt;, &lt;to-db&gt;, &lt;from-hostname&gt;);
</pre>
</li>
<li>Lock, Snapshot and unlock<br />
sync command supports a lock option that allows to sa fely snapshot the database datafiles. while locked, all write operations are blocked, although read operations are still allowed. after snapshotting, use the unlock command to unlock the database an allows locks again.</p>
<pre class="brush: plain; title: ; notranslate">
&gt; use admin
&gt; db.runCommand({sync: true, lock: 1});
unlock command:
db.$cmd.sys.unlock.findOne();
</pre>
<p>while the database can be read while locked for snapshoting, if a write is attempted, this will block readers due to the database&#8217;s use of read/write lock. (issues 1423);
</li>
<li>Index related commands:ensureIndex() is a helper function. its implementation creates an index by adding its into into the system.indexes collection
<pre class="brush: plain; title: ; notranslate">
&gt; use test
&gt; db.mycollection.ensureIndex(&lt;keypattern&gt;);
// same as
&gt; db.system.indexes.insert({name: 'name', ns: 'namespaceToIndex', key: &lt;keypatter&gt;});
</pre>
</li>
<li>you can query system.indexes to see all indexes for a collection foo in db test.
<pre class="brush: plain; title: ; notranslate">
&gt; db.system.indexes.find({ns: 'test.foo'});
</pre>
</li>
<li>dropping indexes
<pre class="brush: plain; title: ; notranslate">
db.mycollection.dropIndex(&lt;name_or_pattern&gt;);
db.mycollection.dropIndexes(); &lt;-- drops all the indexes
e.g.
t.dropIndex({name: true});
</pre>
</li>
<li>index namespace:<br />
each index has a namespace of its own for the btree bucket. the namespace is:<br />
&lt;collectionamespace&gt;.$&lt;indexname&gt;<br />
this is an internal namespace that cannot be queried directly.
</li>
<li>Last error commands:Since mongodb doesn&#8217;t wait for a response by default when writing to the database, a couple of commands exist for ensuring that these operations have succeeded. these commands can be invoked automatically with many of the drivers when saving and updating in the &#8216;safe&#8217; mode.
<pre class="brush: plain; title: ; notranslate">
db.$cmd.findOne({getlasterror:1});
or
db.runCommand('getlaterror');
or helper
db.getLastError();
</pre>
</li>
<li>
getlaterror is primarily useful for write operation (although it is set after a command or query to) write operations by default do not have a return code. this saves the client from waiting for client/server turnarounds during write operations. one can always call getlasterror if one wants to return a code.</li>
<li>
db.restError(); removes error that might have happened in the past, gets called before any comand is executed.</li>
<li>stats for a collection
<pre class="brush: plain; title: ; notranslate">
&gt; use comedy
&gt; db.cartoon.validate();
</pre>
<p>returns stats about the collection along with the number of records etc
</li>
<li>Mongo Metadata:<br />
The &lt;dbname&gt;.system.* namespace in mongoDB are special and contain database specific information. the systems include:</p>
<ul>
<li>system.namespcaes list all namespaces</li>
<li>system.indexes lists all indexes</li>
<li>system.profile stores database profiling information.</li>
<li>system.users lists users who may access the database</li>
<li>local.sources stores replica slave configuration data and state.</li>
<li>information on the structure of a stored object is stored within the object itself.</li>
</ul>
</li>
<li>
Collections:<br />
mongo collections are essentially named grouping of documents. you can think of them roughly equivalent to relational database tables. It is a collection of a BSON documents.<br />
- collection name should begin with letters and underscore. $ is reserved.<br />
the max size of a collection name is 128 char</li>
</ul>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/23/notes-on-mongodb-quickstart-guide-to-mongodb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PuppetConf 2011 &#8211; Architecting for the Cloud: AWS Cloud Formation and Puppet &#8211; Jinesh Varia</title>
		<link>http://blog.rajatpandit.com/2011/12/23/puppetconf-2011-architecting-for-the-cloud-aws-cloud-formation-and-puppet-jinesh-varia/</link>
		<comments>http://blog.rajatpandit.com/2011/12/23/puppetconf-2011-architecting-for-the-cloud-aws-cloud-formation-and-puppet-jinesh-varia/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 11:02:45 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=733</guid>
		<description><![CDATA[Excellent presentation, wish I had seen this before, For me slide 60 was pretty much the summary of the various cloud implementation routes, rest of it usually is just means...]]></description>
			<content:encoded><![CDATA[<p>Excellent presentation, wish I had seen this before, For me slide 60 was pretty much the summary of the various cloud implementation routes, rest of it usually is just means of getting to it. Best use of your next 45mins.</p>
<p><iframe width="560" height="315" src="http://www.youtube-nocookie.com/embed/xpsEKC0tTGk" frameborder="0" allowfullscreen></iframe></p>
<div style="width:425px" id="__ss_9398955"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/AmazonWebServices/aws-cloudformation-and-puppet-at-puppetconf-jinesh-varia" title="AWS CloudFormation and Puppet at PuppetConf - Jinesh Varia" target="_blank">AWS CloudFormation and Puppet at PuppetConf &#8211; Jinesh Varia</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/9398955" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
<div style="padding:5px 0 12px"> View more presentations from <a href="http://www.slideshare.net/AmazonWebServices" target="_blank">Amazon Web Services</a> </div>
</p></div>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/23/puppetconf-2011-architecting-for-the-cloud-aws-cloud-formation-and-puppet-jinesh-varia/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Setting up Trac, SVN and Agilo on RHEL 5.x</title>
		<link>http://blog.rajatpandit.com/2011/12/23/setting-up-trac-svn-and-agilo-on-rhel-5-x/</link>
		<comments>http://blog.rajatpandit.com/2011/12/23/setting-up-trac-svn-and-agilo-on-rhel-5-x/#comments</comments>
		<pubDate>Fri, 23 Dec 2011 09:06:14 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Devops]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[agile]]></category>
		<category><![CDATA[agilo]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[trac]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=709</guid>
		<description><![CDATA[As part of yet another transformational project I am about to start from the very scratch. This time right from setting up the agile project management tools. I decided to...]]></description>
			<content:encoded><![CDATA[<p>As part of yet another transformational project I am about to start from the very scratch. This time right from setting up the agile project management tools. I decided to go with <a href="http://trac.edgewall.org">trac</a> (running <a href="http://www.agilofortrac.com/">agilo</a> on top of it) for the agile delivery, svn for code versioning. This combination works very well together because:</p>
<ul>
<li>You can have your product backlog, sprint backlog and tasks all in one place</li>
<li>Agilo manage your backlogs and provide fancy metrics of how your sprint is doing</li>
<li>SVN ties well into trac which means you can tie commits back into sprint tasks, which means you have a traceability matrix of the tasks/defects and the code changes made to close it</li>
<li>Trac also helps you manage a milestone so you can have a high-level view of how you are doing against your deadlines to meet a milestone</li>
</ul>
<p>You can read more about them here <a href="http://www.agilofortrac.com/en/features/">Agilo</a> and <a href="http://trac.edgewall.org/wiki/TracFeatures">Trac</a><br />
<a href="http://blog.rajatpandit.com/wp-content/uploads/2011/12/Agilo_for_Scrum_Open_Source_Scrum_Tool.jpg"><img src="http://blog.rajatpandit.com/wp-content/uploads/2011/12/Agilo_for_Scrum_Open_Source_Scrum_Tool-300x296.jpg" alt="" title="Agilo_for_Scrum_Open_Source_Scrum_Tool" width="300" height="296" class="alignleft size-medium wp-image-715" /></a><br />
You first need to enable repoforge for your RHEL install and then install the required packages</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# rpm -Uhv http://apt.sw.be/redhat/el5/en/x86_64/rpmforge/RPMS//rpmforge-release-0.3.6-1.el5.rf.x86_64.rpm
[root@localhost ~]# yum -y install subversion trac mod_dav_svn mod_python
</pre>
<p>Now you need to create the directories for svn repos, trac project and auth directory. I choose <code>/var/www/</code> but you can choose anything else you want.</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# mkdir -p /var/www/svn/svnrepos #holds the svn repos
[root@localhost ~]# mkdir -p /var/www/trac #trac base folder
[root@localhost ~]# mkdir -p /var/www/svn/auth #holds the htaccess files
[root@localhost ~]# htpasswd -c /var/www/svn/auth/svn.htpasswd svnuser
[root@localhost ~]# svnadmin create /var/www/svn/svnrepos/secret-project #create svn repo
</pre>
<p>Now create the initial svn folders/files in the repo</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# svn mkdir file:///var/www/svn/svnrepos/secret-project/branches  \
file:///var/www/svn/svnrepos/secret-project/tags  \
file:///var/www/svn/svnrepos/secret-project/trunk  \
-m 'creating directories for initial import'

Committed revision 1.
</pre>
<p>Now create your first trac project</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# trac-admin /var/www/trac/secret-project \
permission add tracuser TRAC_ADMIN
</pre>
<p>You will need then require to go the settings of trac to give it the svn repo patch and then using trac-admin to call resync.</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# trac-admin $ENV repository resync &quot;secret-project&quot;
</pre>
<p>You would also require a post commit hook to ensure that trac gets updated every time a new commit is made. There is plenty of information available on <a href="http://trac.edgewall.org/wiki/CommitTicketUpdater">http://trac.edgewall.org/wiki/CommitTicketUpdater</a>, but basically you need is an svn post commit hook which calls <code>trac-admin $ENV changeset added 'secret-project'</code>.</p>
<p>Installing Agilo can be done using a plugin. If you have <code>easy_install</code> installed even better. Just follow the instructions as follows</p>
<pre class="brush: plain; title: ; notranslate">
[root@localhost ~]# easy_install &lt;agilo&gt;.egg
[root@localhost ~]# cd /var/www/trac/britebill-holepunch/conf
[root@localhost conf]# trac-admin /var/www/trac/secret-project/ upgrade #upgrade trac post plugin install
Creating Product Backlog...
Creating Sprint Backlog...
Upgrade done.
[root@localhost conf]# trac-admin /var/www/trac/britebill-holepunch/ wiki upgrade #upgrade trac wiki as well
</pre>
<p><a href="http://blog.rajatpandit.com/wp-content/uploads/2011/12/screenshot_A_11.png"><img src="http://blog.rajatpandit.com/wp-content/uploads/2011/12/screenshot_A_11-300x179.png" alt="" title="screenshot_A_1" width="300" height="179" class="alignleft size-medium wp-image-713" /></a></p>
<p>Now you can use the web interface to configure the project even more, adding your backlogs, tickets etc. Agilo also allows you to import your backlog from an xls sheet which is great as most product managers are still stuck in the xls era and refuse to let it go.</p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/23/setting-up-trac-svn-and-agilo-on-rhel-5-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automation for packaging websites</title>
		<link>http://blog.rajatpandit.com/2011/12/21/automation-for-packaging-websites/</link>
		<comments>http://blog.rajatpandit.com/2011/12/21/automation-for-packaging-websites/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 00:24:55 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=678</guid>
		<description><![CDATA[For the ones who are following up my earlier blog post about packaging up website code, I had written about how you could also automate the process using phing/ant. I...]]></description>
			<content:encoded><![CDATA[<p>For the ones who are following up my earlier blog post about <a href="http://blog.rajatpandit.com/2011/12/19/packaging-up-websites-for-easy-deployment/">packaging up website code</a>, I had written about how you could also automate the process using phing/ant. I have committed a sample script up on github for anyone who is interested in looking at a sample implementation.</p>
<p>In order to use the phing script you would require to do the following:</p>
<ul>
<li>Clone/download the code from <code>git@github.com:rajatpandit/phing-website-packaging.git</code></li>
<li>Copy the <code>debian</code> folder across to your project</li>
<li>Tweak the files in there to match your projects requirements</li>
<li>The file names ending in .in are the template files that the phing script will take and modify before actually building the package for you</li>
<li>The phing script modifies the files based on two arguments that you provide <code>build.project</code> and <code>build.version</code></li>
<li>The other file you need to look out for for is the <code>install.in</code> which contains the &#8220;from&#8221; and &#8220;to&#8221; locations of the files which will get deployed when the package is installed</li>
<li>The other files would required to be tweaked accordingly</li>
<li>Once you are happy with the changes, copy the package.xml file at the same level as the <code>debian</code> folder and ensure that the required packages are installed (refer to my previous post to know about the names of the packages</li>
<li>Execute the phing script as follows e.g.
<pre class="brush: plain; title: ; notranslate">
$phing -f package.xml -Dbuild.version=1.0 -Dbuild.project=top-secret-project
</pre>
</li>
</ul>
<p>In addition to the basic targets, it also has some additional target to rebuild the meta-information about your local repo. In case you don&#8217;t need one or use one, feel free to take the targets out.</p>
<p>Any questions, suggestions recommendations etc, as always please leave a comment.</p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/21/automation-for-packaging-websites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Packaging up websites for easy deployment</title>
		<link>http://blog.rajatpandit.com/2011/12/19/packaging-up-websites-for-easy-deployment/</link>
		<comments>http://blog.rajatpandit.com/2011/12/19/packaging-up-websites-for-easy-deployment/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 22:59:43 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=669</guid>
		<description><![CDATA[Over the last few years I have seen the emergence of several practices that are typically termed as &#8216;Best Practices for Cloud Hosting&#8217; I have been involved in quite a...]]></description>
			<content:encoded><![CDATA[<p>Over the last few years I have seen the emergence of several practices that are typically termed as &#8216;Best Practices for Cloud Hosting&#8217; I have been involved in quite a few transitions of hosting providers from dedicated data centers to cloud based hosting providers and even to just a different data-center. Hence I shall be posting about these as a series.</p>
<p>As the first part of the series I am documenting about the common problems that most sys-admins have to face when they have to transition an application from a legacy datacenter to a different environment. Years of code/hacks usually the code base dependent on &#8216;assumed&#8217; paths and &#8216;environment variables&#8217;. The other problem that people face is when its required to host the application on multiple servers. Which means when you need to install the latest version of your website you should be able to roll out the new code simultaneously on all the nodes in the cluster and be able to roll back similarly. This means a simple svn/git command is not going to be enough and would require well more than that.</p>
<p>In addition to the above problems there are other things that go hand in hand with the code deployment like your website server configurations (if your app code is dependent on things like apache modules or re-write rules etc) or any other configs like cron jobs etc. You might also want these to be updated (and corresponding services to be restarted) when the new version of code is deployed.</p>
<p>Packaging up the website code as a OS installer solves most of the above problems. You can make an rpm or a debian package out of your website and roll it to your local repository which can then be used to install or rollback to a particular version of your website code.</p>
<p>Since ubuntu is my OS of choice (atleast for now) this post will talk about how to setup a debian package, I might write a followup post for building RPM packages which turns out to equally similar to debian package.</p>
<p>Install the required packages</p>
<pre class="brush: plain; title: ; notranslate">
$ apt-get install dh-make devscripts
</pre>
<p>Now configure the dh_make command you updating some variables in your .bashrc file. </p>
<pre class="brush: plain; title: ; notranslate">
    $ cat &gt;&gt;~/.bashrc &lt;&lt;EOF
    DEBEMAIL=your.email.address@example.org
    DEBFULLNAME=Firstname Lastname
    export DEBEMAIL DEBFULLNAME
    EOF
    $ . ~/.bashrc
</pre>
<p>Checkout our code in your working directory in the structure defined below. This is  where you would be working and creating additional files that the debian package manager would use to build your package. Lets consider our project is called top-secret</p>
<pre class="brush: plain; title: ; notranslate">
 $ mkdir -p top-secret/top-secret-1.0; cd top-secret/top-secret-1.0
 $ svn co &lt;path to repo&gt;/trunk .
 $ tar -cvzf top-secret-1.0.tar.gz top-secret-1.0
</pre>
<p>The 1.0 is just an indicative version, once you have understood the process you can automate the process of creating directories with version numbers using automation scripts like phing/ant etc.</p>
<p>Now create the initial template files:</p>
<pre class="brush: plain; title: ; notranslate">
rp@chlorine:~/packaging/top-secret/top-secret-1.0$ dh_make -f ../top-secret-1.0.tar.gz
Type of package: single binary, indep binary, multiple binary, library, kernel module, kernel patch or cdbs?
 [s/i/m/l/k/n/b] s

Maintainer name : Rajat Pandit
Email-Address   : rp@rajatpandit.com
Date            : Tue, 24 May 2011 09:08:35 +0100
Package Name    : hello-sh
Version         : 1.0
License         : blank
Using dpatch     : no
Type of Package : Single
Hit &lt;enter&gt; to confirm:
Currently there is no top level Makefile. This may require additional tuning.
Done. Please edit the files in the debian/ subdirectory now. You should also
check that the hello-sh Makefiles install into $DESTDIR and not in / .
</pre>
<p>This process also builds a new tar file as well.</p>
<pre class="brush: plain; title: ; notranslate">
rp@chlorine:~/packaging/hello-sh$ ls -l
total 12
drwxr-xr-x 3 rp rp 4096 2011-05-24 09:08 top-secret-1.0
-rw-r--r-- 1 rp rp  167 2011-05-24 09:00 top-secret_1.0.orig.tar.gz
-rw-r--r-- 1 rp rp  167 2011-05-24 09:00 top-secret-1.0.tar.gz
</pre>
<p>Additionally it will also create a bunch of files under a new folder <code>debian</code></p>
<pre class="brush: plain; title: ; notranslate">
debian/
├── top-secret.cron.d
├── changelog
├── compat
├── control
├── copyright
├── docs
├── files
├── install
├── postinst
├── postrm
├── README
├── rules
└── source
    └── format
</pre>
<p>These files are the ones that are used by the package manager to build a debian package.<br />
You can learn about what each file does in the debian package managing guide <a href="http://www.debian.org/doc/manuals/maint-guide/dother.en.html">http://www.debian.org/doc/manuals/maint-guide/dother.en.html</a> which is why I won&#8217;t repeat that here.</p>
<p>The only important thing you need to remember is that the folder outside <code>debian</code> folder should be what would be the install path. Which means if your code has to go in <code>/opt/vs/websites/top-secret</code> the code should be in top-secret-1.0/op/vs/websites/top-secret</code></p>
<p>and also the file <code>install</code> should contain which folder needs to be copied where. This information should be one line per folder. For example if my code contains</p>
<pre class="brush: plain; title: ; notranslate">
├── b
│   ├── d
│   │   └── d
│   └── foo.php
</pre>
<p>and I want 'b' to be installed in /var/www/b and bla.php in /var/www/bin/bla.php then my install file would look like this:</p>
<pre class="brush: plain; title: ; notranslate">
b /var/www/b
bla.php /var/www/bin/bla.php
</pre>
<p>Building the package is also very simple. If you don't want to worry about signing your packages then you can just use the following command:</p>
<pre class="brush: plain; title: ; notranslate">
$debuild -us -uc
</pre>
<p>and you would get a .deb file in the end. You can check the contents of the debian file using</p>
<pre class="brush: plain; title: ; notranslate">
$ dpkg -c top-secret-1.0.deb
</pre>
<p>and that will list the contents of the the debian file along with its location for installation. </p>
<p>Now to make this process a little more streamlined you can do a few other things:</p>
<ul>
<li>Setup a local debian repository, which is accessible by all web servers, serve it over http ideally</li>
<li>Setup the local repo to point this repository so that all the webservers get to know about it</li>
<li>Setup some form of automation that running the commands, modifying the debian configuration files etc be done using ant or phing</li>
<li>Take the automation to the next level and call the script using Hudson</li>
</ul>
<p>This will give you a nice workflow with the wonderful UI from hudson to managing building a webpackage and then deploying it to the web server. </p>
<p>If you have further ideas of where this could be used please share your thoughts in your comments. I would like to credit the initial idea of packaging websites in RPM to the lovely sysadmins at IPCMedia. I modified the approach and moved from their technology to work for the ubuntu platforms.</p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/19/packaging-up-websites-for-easy-deployment/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Facebook Check-in deals</title>
		<link>http://blog.rajatpandit.com/2011/12/14/facebook-check-in-deals/</link>
		<comments>http://blog.rajatpandit.com/2011/12/14/facebook-check-in-deals/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 21:27:23 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=627</guid>
		<description><![CDATA[Just readup about the new feature on facebook allowing individual business owners deals on facebook. its a brilliant idea for local businesses to attract, retain and build their customer base....]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft" style="margin: 5px;" title="Facebook Check-in Deals" src="https://s-static.ak.facebook.com/rsrc.php/v1/y8/r/tSUJkdwzEqR.png" alt="" width="271" height="154" />Just readup about the new feature on facebook allowing individual business owners deals on facebook. its a brilliant idea for local businesses to attract, retain and build their customer base. Videos explaining what its about and the detailsabout it are here: <a href="https://www.facebook.com/deals/checkin/business/">https://www.facebook.com/deals/checkin/business/</a></p>
<p>To summarize its benefits:</p>
<ul>
<li>Build Customer Loyalty: Award repeat customers by offering them a discount</li>
<li>Spread the word: Average user has 130+ friends, every check appears on their wall, helping spread the name of your business</li>
<li>Acquire new customers: Customers can find you based on your deals based on the location in which they are present. Offering deals gives them an incentive to come and visit you.</li>
</ul>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/12/14/facebook-check-in-deals/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Apache Bench for benchmarking web servers</title>
		<link>http://blog.rajatpandit.com/2011/08/21/apache-bench-for-benchmarking-web-servers/</link>
		<comments>http://blog.rajatpandit.com/2011/08/21/apache-bench-for-benchmarking-web-servers/#comments</comments>
		<pubDate>Sun, 21 Aug 2011 09:34:29 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=615</guid>
		<description><![CDATA[I am nearly at the end of the project I had started for Infrastructural transformation for a client. The application is now fully functional on AWS. It has a horizontally...]]></description>
			<content:encoded><![CDATA[<p>I am nearly at the end of the project I had started for Infrastructural transformation for a client. The application is now fully functional on AWS. It has a horizontally scalable web tier with no sticky sessions, db running on RDS with A-Z Deployment and another instance running solr and memcache. It has various end points to extend itself and some day I am go to write more about the lessons learnt and the approach itself. </p>
<p>However more interestingly I decided to compare the performance of the initial dedicated hosting by bytemark and by the current aws setup. Now, I want to be clear about this, that I am not comparing a like for like setup. The dedicated hosting has everything running on the same machine and its probably a 8core dedicated box. On the AWS setup we have 2 core EC2 instances running the web-tier and currently two nodes behind the load balancer.</p>
<p>So this is what I did to get statistics.</p>
<pre class="brush: bash; title: ; notranslate">
$ ab -k -n 10000 -c 5 -g bytemark.csv http://bla.com/
$ ab -k -n 10000 -c 5 -g aws.csv http://beta.bla.com/
</pre>
<p>This gave me enough data against which I could plot some results. One of the options was to use MS Excel but lifes two short and my laptop doesn&#8217;t have a million gigs of ram, so i decided to use gnuplot for this instead.</p>
<p>here&#8217;s what my setup on plotter.p looks like:</p>
<pre class="brush: bash; title: ; notranslate">
set terminal png
set output &quot;webserver-comparison.png&quot;
set title &quot;ab -n 10000 -c 2&quot;
set size 1,0.9
set grid y
set xlabel &quot;Request&quot;
set ylabel &quot;Response Time (ms)&quot;
plot &quot;bytemark.csv&quot; using 9 smooth sbezier with lines title &quot;nodejs&quot;, \
       &quot;aws.csv&quot; using 9 smooth sbezier with lines title &quot;nodejs random timeout&quot;
</pre>
<p>You can now go ahead and generate the required graph</p>
<pre class="brush: bash; title: ; notranslate">
$ gnuplot plotter.p
</pre>
<p>This is what the end result looks like:<br />
<a href="http://blog.rajatpandit.com/wp-content/uploads/2011/08/webserver-stats.png"><img src="http://blog.rajatpandit.com/wp-content/uploads/2011/08/webserver-stats-300x225.png" alt="" title="webserver-stats"  class="alignleft" /></a></p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/08/21/apache-bench-for-benchmarking-web-servers/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>What happened to new posts?</title>
		<link>http://blog.rajatpandit.com/2011/06/22/what-happened-to-new-posts/</link>
		<comments>http://blog.rajatpandit.com/2011/06/22/what-happened-to-new-posts/#comments</comments>
		<pubDate>Wed, 22 Jun 2011 06:35:29 +0000</pubDate>
		<dc:creator>rp</dc:creator>
				<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http://blog.rajatpandit.com/?p=585</guid>
		<description><![CDATA[I have been so far away from any of the blogging stuff for ages now. I primarily attribute that to a really busy last few months at IPCMedia and then...]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.rajatpandit.com/wp-content/uploads/2011/06/where_am_i.png"><img src="http://blog.rajatpandit.com/wp-content/uploads/2011/06/where_am_i-300x262.png" alt="" title="where_am_i" width="300" height="262" class="alignleft size-medium wp-image-586" /></a>I have been so far away from any of the blogging stuff for ages now. I primarily attribute that to a really busy last few months at IPCMedia and then starting a new job at Accenture. Also while I was at IPCMedia I was also working on a Infrastructural Transformation project for a startup which was very interesting.<br />
I learnt a lot in that process, things I thought I knew were just a small piece of the puzzle, there was a lot more to it and I shall cover that over the next few posts. As the project comes to a closer to an end, I shall be writing posts with my notes about what I gathered from various software components I used during the entire process and hopefully someone would find them useful. </p>
<div id="in_post_ad_bottom_1" style="clear:both;margin:0;padding:0;"><div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-bp */
google_ad_slot = "7787511801";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="brp-bp-234">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-4254382394977039";
/* brp-234x60-BP-1 */
google_ad_slot = "9111022353";
google_ad_width = 234;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div></div><div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.rajatpandit.com/2011/06/22/what-happened-to-new-posts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

