Tuesday, May 29, 2012

Petrol car versus diesel car (part 2)

For the earlier part please refer to http://jayant7k.blogspot.in/2006/10/petrol-engine-versus-diesel-engine.html

In this blog i am trying to create a calculation sheet which can be used to figure out - if you go for a diesel car, when would you be able to recover the cost of purchasing the car - as to spending in petrol.

Government in india loves petrol. It is used generally by the middle class with small cars and 2 wheelers and who rarely vote. People who fall below the middle class mostly travel using public transport. And people who are above the middle class generally have long cars powered by diesel engines. The government finds it difficult to increase the price of diesel - due to the ripple effect it will cause in the price of food commodities and the overall inflation. So raising the price of petrol seems the only viable option - to cater to the loss due to subside on diesel and cooking gas - without effecting the government's vote bank.

And ofcourse the amount of tax the government is able to make out of fuel is really good. How the tax amount is used - is a blind spot for the residents of india. We do not see any improvement in roads - jams are always there. It has been more than 60 years since independence and we still are struggling in providing the basic necessities like electricity and water to the general public. It seems valid that there should be a fine on the "government" for unable to accomplish what it has been promising for ages - food, clothes, electricity, water and home.

But lets focus on diesel cars. The new diesel cars from tata and fiat have really long maintenance schedules. Earlier older diesel engines need quick maintenance. Most petrol engines need a service in every 5K kms - or at max 10K kms. On the other hand diesel engines in tata and fiat need maintenance every 15K kms or once a year. This brings down the cost of ownership of diesel engines to a lot less.

Maintenance set aside, a simple table can be used to figure out how long it will take to recover the "extra" cost of diesel.



A B C D

## Petrol Diesel Difference
1 Price per litre 71 41
2 average 14 12
3 rs per km 5.0714285714 (=B1/B2) 3.4166666667 (=C1/C2)
4 kms per day 100 100
5 car price 500000 600000 100000 (=C5-B5)
6 cost per day 507.1428571429 (=B3*B4) 341.6666666667 (=C3*C4) 165.4761904762 (=B6-C6)





7 Days to recover cost

604.3165467626 =(D5/D6)
8 Months

20.1438848921 = (D7/12)




As you see, with petrol and diesel at 71 and 41 respectively, and giving average of 14 and 12 respectively - the cost of owning a diesel car will be recovered in around 20 months (1.5 years), provided everyday run in 100 kms and the difference in price is 1 Lakh. Feel free to copy the info on an excel sheet and try altering the numbers to suit your needs and see when would you be able to recover the cost - if you intend to purchase a diesel car.

Tuesday, May 01, 2012

Deployments

Deployments are a critical phase of any project. In the "stone age", developers used to simply scp the files required into production. And there used to be issues when you are dealing with multiple http servers. Keeping all the servers in sync was always the issue.

Then capistrano came into picture. It made deployment of ruby/rails apps very easy. Me and a few other people went ahead and modified it to deploy code into production for php apps as well. But it was a tricky job since capistrano was originally designed to work for ruby/rails apps. Here is a sample capistrano code that sucks out code from svn and pushes it to multiple web servers - and then runs some specific post deployment tasks on them

deploy.rb

set :application, "app"
set :repository,  "http:///tags/TAG102"
set :imgpath, "/var/images"

# svn settings
set :deploy_via, :copy
set :scm, :subversion
set :scm_username, "svn_username"
set :scm_password, "svn_password"
set :scm_checkout, "export"
set :copy_cache, true
set :copy_exclude, [".svn", "**/.svn"]

# ssh settings
set :user, "server_username"
set :use_sudo, true
default_run_options[:pty] = true

#deployment settings
set :current_dir, "html"
set :deploy_to, ""
set :site_root, "/var/www/#{current_dir}"
set :keep_releases, 3

#web servers
role :web, "192.168.1.1","192.168.1.2","192.168.1.3"

#the actual script
namespace :deploy do
    desc <<-DESC
  deploy the app
    DESC
    task :update do
      transaction do
        update_code
            symlink
        end
      end

    task :finalize_update do
      transaction do
        sudo "chown -R apache.apache #{release_path}"
        sudo "ln -nfs #{imgpath}/images #{release_path}/images"     
      end
    end

    task :symlink do
      transaction do
            puts "Symlinking #{current_path} to #{site_root}."
            sudo "ln -nfs #{release_path} #{site_root}"
      end
    end


    task :migrate do
      #do nothing
    end

    task :restart do
      #do nothing
    end   
end

This sucks out the code from the svn repository. creates a tar on local. Scps it to production web servers. Untars it to the specified location. Runs all the tasks specified in finalize_update and finally changes the symlink of "html" directory to the new deployed path. The good point about capistrano is that you are almost blind as to what happens in the backend. The bad point is that since you are blind, you do not know how to do what you want to do. It would need a bit of digging and a bit of tweaking to get your requirements fulfilled by this script.

Now lets check fabric.

Installation is quite easy using pip.

sudo pip install fabric

In case you like the old fashioned way, you can go ahead and download the source code and do a

sudo python setup.py install

To create a fabric script, you need to create a simple fab file with whatever you require. For example, if you need to run a simple command like 'uname -a' on all your servers, just create a simple script fabfile.py with the following code

from fabric.api import run

def host_type():
        run('uname -a')

And run the script using the following command

$ fab -f fabfile.py -H localhost,127.0.0.1 host_type

[localhost] Executing task 'host_type'
[localhost] run: uname -a
[localhost] Login password:
[localhost] out: Linux gamegeek 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

[127.0.0.1] Executing task 'host_type'
[127.0.0.1] run: uname -a
[127.0.0.1] out: Linux gamegeek 3.2.0-24-generic #37-Ubuntu SMP Wed Apr 25 08:43:22 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Done.
Disconnecting from localhost... done.
Disconnecting from 127.0.0.1... done.

A simple fabric script which can do whatever the earlier capistrano script was doing is here.

fabfile.py

from __future__ import with_statement
from fabric.api import *
from fabric.operations import local,put

def production():
  env.user = 'server_username'
  env.hosts = ['192.168.1.1','192.168.1.2','192.168.1.3']
  env.deploy_to = ''
  env.site_root = '/var/www/html'
  env.tag_name = 'tag101'
  env.repository = {  'url':'http:///tags/TAG101', \
            'username': 'svn_username', \
            'password': 'svn_password', \
            'command': 'svn export --force', \
          }
  env.image_path = '/var/images'

def deploy():
  checkout()
  pack()
  unpack()
  symlinks()
  makelive()

def checkout():
  local('%s --username %s --password %s --no-auth-cache %s /tmp/%s' % \
    (env.repository['command'], env.repository['username'], env.repository['password'], env.repository['url'], env.tag_name));

def pack():
  local('tar -czf /tmp/%s.tar.gz /tmp/%s' % (env.tag_name, env.tag_name))

def unpack():
  put('/tmp/%s.tar.gz' % (env.tag_name), '/tmp/')
  with cd('%s' % (env.deploy_to)):
    run('tar -xzf /tmp/%s.tar.gz' % (env.tag_name))

def symlinks():
  run('ln -nfs %s/images %s/%s/images' % (env.image_path, env.deploy_to, env.tag_name))

def makelive():
  run('ln -nfs %s/%s %s' % (env.deploy_to, env.tag_name, env.site_root))


The good point is that i have more control on what i want to do using fabric as compared to capistrano. And it took me a lot less time to cook the fabric recipe as compared to capistrano.

To run this script simply do

fab production deploy

This will execute the tasks production and deploy in that order. You can have separate settings for staging and local in the same script. You can even go ahead and create your own deployment infrastructure and process to do whatever you want without running into any restrictions.

cfengine - a beginners guide A tool to automate infra...