Setting Up and Managing Multiple SSH Accounts for Drush on Mac/Linux

It may be the case, you have multiple ssh connections some for github accounts and some for one or more virtual boxes for Drupal sites. In this post, we cover how to generate, configure and manage multiple SSH accounts for drush. In addition, we go over how to overcome the error ‘ssh-copy-id: command not found ‘ that happens for Mac machines when trying to setup ssh keys via drush command ‘pushkey’

Generating Public/Private SSH Key Pair

For each different ssh account, you would generate ssh public/private key pair as following:

ssh-keygen -t rsa -C "user@hostname.com"

By default, this will store the generated key pairs(two files one with .pub extensions) in the directory you run the command from. We moved it into $HOME/.ssh directory and we will be referring to this directory in this post

Manage SSH Keys

You can manage multiple SSH keys by creating host aliases for each ssh key pair. The host aliases are defined in the $HOME/.ssh/config file and all they do is reference the keys per host alias as following

Host virtual-box-main
        HostName hostdomain.com
        User user-name
        IdentityFile ~/.ssh/id_rsa_virtual_box

Host another-host-alias
        HostName some-remote-box.com
        User ssh-user
        IdentityFile ~/.ssh/private_key_gen_above

Here the host alias is ‘virtual-box-main’. The ‘hostname’ is actual domain name to the server you like to ssh. The ‘user’ is the actual ssh user account that will be used to ssh into the server. At last, the ssh key pair is referenced via ‘IdentityFile’ that was generated in the above step.

So, you can repeat the above steps to generate ssh key pairs for each ssh remote account. Then configure host alias by adding another entry as specified above for each different ssh login you need.

Setup Drush

Once you have the ssh host alias setup, then to configure drush via the alias(one location $HOME/.drush/aliases.drushrc.php) as following:

$aliases['ds.prod'] = array(
	'remote-host' => 'virtual-box-main',
	'remote-user' => 'root',
	'root' => '/home/websites/site',
	'uri' => 'http://site.com',
    );

Here the host alias configure in ssh is specified ‘remote-host’, so when drush makes the ssh connection it will look it up the alias to identify ssh key to use for login

If you try to connect with the current setup:

drush @ds.prod st

You will get following error:
Permission denied (publickey,password).

This is because the remote machine needs to have the ssh public key in order to be able authenticate. Lets push the key:

drush pushkey @ds.prod

This function copies the ssh key into the server for ssh authentication.

For Mac, this will result into the following error because Mac doesn’t have the function ‘ssh-copy-id’
ssh-copy-id: command not found
So, solution is to copy ssh key manually

Copy Public SSh Key Manually

To copy the public ssh key, run the following:

cat id_rsa_virtual_box.pub | ssh user@virtualbox.com 'cat >> .ssh/authorized_keys' 

This pipes the ssh key and then logs into the virtual server and pasts the key into authorized_keys file. You may be missing the .ssh folder on the remote server. In that case, you make it create one as following:

cat id_rsa_virtual_box.pub | ssh user@virtualbox.com 'umask 077; mkdir -p .ssh ; cat >> .ssh/authorized_keys'

Now, running:

drush @some.alias st

It should be displaying the status of the site on remote server

Troubleshooting

1. Test SSH Authentication

To test any of your SSH Aliases setups:

ssh virtual-box-main

Here, we test the alias ‘virtual-box-main’. This will prompt for password if logging in for the first time. All other times it logs you in without password
Note: for ssh services that has turned off interactive mode such as Git, you use -T flag:

ssh -T git-ssh-alias

This will confirm if your ssh is setup correctly or not

2. Permission denied (publickey,password).

You will get this message if you haven’t set up the ssh as described in this post

3. ‘pushkey’ could not be found drush

This is because the push key function is addition and needs to be downloaded as following:

drush dl drush_extras

This will download and install drush_extras module that includes “pushkey” command

4. “sudo: no tty present and no askpass program specified”

This is issue comes up when you open ssh without tty session. It can be solved in 2 ways depending on how much access you have on remote instance or whatever the remote instance has the capability of NOPASSWORD

  1. Turn on NOPASSWORD on remote instance as described here:
    http://askubuntu.com/questions/192050/how-to-run-sudo-command-with-no-password/443071#443071
  2. Configure Drush to pass in credentials at time of ssh-ing. Its being done by editing .drush/drushrc.php and adding following line:
    $options['ssh-options'] = '-o PasswordAuthentication=no -i $HOME/.ssh/id_rsa/lamp_vbox';
    

    Here the lamp_vbox is the private key generated by ssh-keygen

5. WARNING: UNPROTECTED PRIVATE KEY FILE!

The permissions need to be reset:

sudo chmod 600 /path/.ssh/id_rsa/lamp_vbox
sudo chmod 600 /path/.ssh/id_rsa/lamp_vbox.pub
sudo chmod 644 /path/.ssh/known_hosts
sudo chmod 755 /path/.ssh
References

http://mail-archives.apache.org/mod_mbox/hadoop-mapreduce-user/201210.mbox
http://blogs.uoregon.edu/developments/2012/06/21/bash-function-ssh-copy-id-for-mac/
http://www.drush.org/sites/default/files/attachments/DGD7-Drush.pdf
http://stackoverflow.com/questions/3844393/what-to-do-about-pty-allocation-request-failed-on-channel-0

Upgrading Drupal Core and Modules via Drush

There may be a time when it is a time to upgrade your drupal core and modules. It may also be a situation, when some feature or functionality doesn’t work as it should be. In that case, it may be that one of the modules are out of date causing it malfunction.

Its recommended to back up the database and the code of the Drupal site before upgrading

Step 1. Check The Status

To check status on what is out of date or which module has an upgrade available run:

drush cron

This will update the ‘Status Report’. To see the report, login as Admin and go to Reports->Status Report

Step 2. Upgrade Modules and the core

To upgrade the modules and the core, run

drush upc

This will start an interactive mode and walk through the process upgrading each module and eventually the core

To see available options ‘drush upc –help’ in situations where you don’t want to update core but only modules, for example

drush upc --no-core

This will only update modules and skip the core update.

Step 3. Updating Database

To update database, run

drush updb

This will run all database updates
To see available options run ‘drush updp –help’

Step 2 & 3: To upgrade code and database at once

To upgrade modules, core together with database udpates, run:

drush up

Its combines the step 2 and 3. For finding available options, run ‘drush up –help’

Other

1. Find Current project info

drush status

This will display current Drupal and Drush vers, database driver, php configuration, etc.

Useful Lins

Updating drupal core and modules

Drupal install with Drush

In this posts, we list steps to install Drupal site utilizing Drush

Tested: Drush 5.8, Mac 10.7.5, MySQL 5.0.10

Step-1. Download and Install

1)Download Drupal
To download Drupal, run the following in command line:

drush pm-download drupal

This creates folder drupal-x.ver and downdloads drupal. if need specific version, then replace ‘drupal’ to ‘drupal-7.18’ for example

drush pm-download drupal-7.18

2) Rename default folder
After downloading drupal, the drupal code is in default folder – drupal-x.ver. Perhaps, you like to move into name of your website.

sudo mv drupal-7.18 nameOfMySite

3)Create and Set up Database(DB)
Here is how to setup database from the command line interface:

mysql -u USER -p
mysql>create database NAME_OF_NEW_DB;
mysql>GRANT ALL PRIVILEGES ON NAME_OF_NEW_DB.* TO db_user@'localhost' IDENTIFIED BY 'db_passwd';
mysql>flush privileges;

In line one, we login the mysql server run locally. In line two, the new database is created with name ‘NAME_OF_NEW_DB’. In line three, a new user is crated for the new database and all privileges are granted for that user. In last line, the cache is flushed for our changes to take an effect.

4) Install Drupal
Install Drupal as follows:

cd nameOfMySite
sudo drush si --db-url=mysql://dbUser:dbPass@localhost:3306/nameOfDb --account-pass=adminPassword

Here the dbUser, dbPass and nameOfDb are the credentials created in step 3

Besides installing Drupal, it also configures database. The ‘–acount-pass=adminPassword’ specifies password for admin user for the Drupal website.

5. Configure Local DNS
To rout the request to your local drupal instance, update the hosts file. For Unix based systems, it is located at /etc/hosts. If your local domain name is going to be test.com, then insert the following line in the /etc/hosts file:

127.0.0.1       test.com

6. Configure Virtual Host
At last, configure the virtual host for your new site in Apache web server. Depending where is your Apache Web server installed and what version, the location for virtual host settings my differ. In our case, it is located at apacheRoot/conf/extra/httpd-vhosts.conf. So, to configure the virtual host for our new drupal instance, we would insert the following:

 
...
<VirtualHost *:80>
    DocumentRoot "/path/to/drupal_root_dir"
    ServerName test.com
    <Directory /path/to/drupal_root_dir>
        Options FollowSymLinks
        AllowOverride All
    </Directory>
</VirtualHost>
...

In line 3 and 5, the directory of our new drupal site is installed. In line 4, the local domain that we configured in previous step is specified.
Afterwards, Restart Apache server to reload virtual hosts configurations

service apache2 restart

or

sudo /root/To/Apache/dir/bin/apachectl restart

This will restart Apache and load the new configurations
!Some Apache Web Server versions need specifically enable the virtual host, then

sudo a2ensite yoursite

7. Test it!
Open browser and point it to the test.com. If it doesn’t work, see the Troubleshooting section below for help.

Step-2 Set up Root directory

If your web server is configured to service the drupal site from the subfolder than:
a)Specify directory from where the drupal site is serviced from.
In  the .htaccess(in site root folder) uncomment line “ReriteBase/drupal” and updated it to the location of your site:

RewriteBase /PathToSite

b)Configure the Drupal base Url
To configure Drupal base, uncommenting $base_url in settings.php file( usually in sites/default/settings.php) as follows:

$base_url = 'http://www.example.com/pathToSite'; 

Media Modules

For making it possible to insert images into text area using WYSIWYG, there are two modules if using WYSIWYG module for your editor solution:

If you are using CKEditor Module for editor solution instead, then the IMCE module is sufficient

The CKEditor works with the above modules. There is currently issue with WYSIGWYG default module to work with CKEditor, but solution is to use the dev(7.x-2.x-dev) module of WYSIGWYG

Step-3 Install other Useful modules

a) JQuery Update – updated jquery module for drupal core (http://drupal.org/project/jquery_update)

drush dl jquery_update-7.x-2.x-dev -y
drush en jquery_update-7.x-2.x-dev -y

Note:As you see, we chose the dev version of jquery_update to ensure it contains lates jquery lib version, however, in your case it may be different. Afterwards, select jquery version you wish your drupal site uses by going into admin->modules->jquery_update->Configure and select version

b) Twitter Bootstrap – see post ‘Installing Twitter Bootstrap with Drupal

c) WYSIWYG [wysiwyg] – install necessary module before downloading and configuring one of the wysiwyg editors. To install:

drush dl wysiwyg
sudo drush en wysiwyg

Once module wysiwyg installed, then enabled it in Admin->Modules->Check ‘wysiwyg’ module and save. Next, press ‘configure’ to see all the available wysiwyg editors with instructions how to install and enable any from the list. Our favorite – WYMEditor

!Alternative to WYSIWYG module is CKEditor Module. While it is limited to CKEditor, it is slick and can be configured well.

d) Admin Menu [admin_menu]- makes the admin menue items to drop down in hierarchal manner instead one level
To install:

drush dl admin_menu
sudo drush en admin_menu

e) Path Auto [pathauto] – provides an option to alias url to whatever you choose or auto generate alias url from title field.

drush dl pathauto
sudo drush en pathauto

Note: the module ‘pathauto’ dependes on module ‘token’. If installed via drush, then the dependency is installed automatically

f) Date [date] – adds field type of Date with nice date picker UI. To install:

drush dl date
sudo drush en date

Afterwards, enable the time pop-up picker in the Admin->Modules section

g) Views[views] – enable to create views that is an excellent feature to aggregate content in custom way for front page or any section  of the page for that matter. To install:

drush dl views
sudo drush en views

Note: You may be interested in better_exposed_filters module for exposing more enhanced filters to user
Note: the module ‘views’ has dependency of module ‘ctools’ that is auto installed with drush

h)Database Migration – for backing up and migrating database, the backup_migrate is good choice

i)Botcha – to stop spam at form submission including user registertion

Step-4 Developers Modules

a)Theme Developer[devel_themer] – helps to see templates used any page, profiling db queries, generate content and other cool stuff. To install:

drush dl devel_themer
drush en devel_themer

!If you install not via drush then make sure your install also the dependencies. With Drush, it does automatically
Few tools from Theme Developer:

  • Go to Structure->Blocks and enable Develpers block. In the Developers blog you can select ‘devel setting’ to enable profiling DB queries
  • Go to Configuration->Development->Generate Content. This generates some content to work with
  • Select ‘Themer info’ right bottom corner to see what templates called, events triggered and variable renedered

b) Block Class IU[block_class] – it enables to add css styling to any block from UI never need to go into code
To install:

drush dl block_class
drush en block_class

c) Install firebug for Drupal. In Firefox select Tools->Add On->Search with keyword ‘firebug’ and select Drupal Firebug add on. Afterward, restart firefox.
That installs for the browser, but then for firebug support in your drupal development site:

drush dl drupalforfirebug
drush en drupalforfirebug

d) Advanced Help [advanced_help] – To access advanced help index (good for developing views). To install

drush dl advanced_help
drush en advanced_help

e)Examples For Developers – examples for custom module development

drush dl examples
drush en examples

f) Coffee[coffee] – is great UI feature to get around quickly. By pressing AlT+D, it opens the input box where you can type the module or admin functionality you want to get/edit or configure. Afterwards, click the link to go there

g)Module Filter [module_filter] – for assistance on navigating around the modules, the module_filter module is great by filtering and adding extra menu in modules section.

h) Module Instructions[module_instructions] – pulls up all ReadMe files easy available to read in the Modules section

Transform for Versioning and Exporting

Drupal has a way to convert all site or parts of the sites functionality into features for ability to version it into code as well as easy migrating. Here are all the modules that will do the work for Drupal 7:
a)Features – makes it easy for you to export features that is content types, views, etc all of which can be called configurations and content Structure. It packages into a custom module that you can transfer on another Drupal instance

b) uuid features – is integration for Features module that adds a capability for exporting content itself not only the content structure. It also supports file exports, services. Make sure you specify which content structures enabled for the feature module at ‘admin/config/content/uuid_features’. Make sure also create missing UUIDs at admin/config/system/uuid

c)StrongArm – It provides ability to feature variables and configurations

d)commerce_features – it provides ability to feature commerce customer profiles, products, tax rates and types.

d)features_extra – One of the features_extra submodules is fe_blocks. This provides an ability to convert block configurations. This especially useful if your site is using context for organizing blocks and you need disable all the blocks in the ‘structure/blocks’

SEO Modules

Besides ‘autopath’ module for url naming, here are other useful SEO related modules

a) XMLSiteMap
[xmlsitemap] – generates xml site map that is submitted to search engines

b) Site Verify
[site_verify] – provides an easy way to verify your site with search engines

c) SEO Checklist
[seo_checklist] – provides a check list for SEO of your site

c) Google Analytics
[google_analytics] – enables google analytics in site

Other

a) Add This
[addthis] – enables your site users to vote and plus(+1) your products

b) Add To Any
[addtoany] – helps readers share, bookmark, and email your pages and articles (aka stories) using any service, such as Facebook, Twitter, Google+, Pinterest, and other.

c)Enable Menu Title in HTML
Twitter Bootstrap and other CSS styling frameworks often use icons class to insert icons in front of title. By default, Drupal doesn’t permit the title contain html. There is a moduel menu_html that allows easy enable title be html

d)Reference Entities
Entity Reference helps to reference other elements. Really good for building some complex data structures vi UI like photo gallery,podcast,etc.

Troubleshooting

1. Error:

Drupal requires you to enable the PHP extensions in the following list (see the system requirements page for more information):gd
Looks like  missing php5-gd2.so lib. Run:

sudo port install php5-gd2
sudo port activate php5-gd2

2. Error:
Command site-install needs a higher bootstrap level to run - you will[error] need to invoke drush from a more functional Drupal environment to run this command.
Make sure you are in the directory of drupal that was downloaded in step 1.

3. Error:

...SQLSTATE[HY000] [1045] Access denied for user 'someuser'@'localhost...

Apparently, the mysql user provided to drush unable connect database. Ensure the user is remote localhost enabled. Here is how to test:

mysql -u someuser -p -h localhost

If not then, you have to enable it as remote user as follows:

mysql>GRANT ALL PRIVILEGES ON *.* TO someuser@'localhost' IDENTIFIED BY 'db_passwd';
mysql>FLUSH PRIVILEGES;

This will make user ‘someuser’ as remote access user from ip of ‘localhost

Rewrite Fails:
If you able to load from root but unable to go any other pages of the drupal website then it likely an issue with rewrite. To troubleshoot, first check that appache is loading mod_rewrite:

apachectl -t -D DUMP_MODULES

This displays all modules loaded by apache web service. Look to see if ‘rewrite_module’ is present. If it is, then ‘rewrite’ loads, but, apparently, it hasn’t been configured correctly. One way is to have virtual host configuring your drupal portal including rewrite as well:

...
<VirtualHost *:80>
    DocumentRoot "/Users/user/Sites/drupal_root"
    ServerName drupal-test.com
    <Directory /Users/user/Sites/drupal_root>
        Options FollowSymLinks
        AllowOverride All
    </Directory>
    ErrorLog "/private/var/log/apache2/drupal-test.com-error_log"
    CustomLog "/private/var/log/apache2/drupal-test.com-access_log" common
</VirtualHost>
...

The highlighted lines configure the overwrite. The DocumentRoot is folder where your drupal site is serviced from. The ServerName is your configured local DNS name in /etc/hosts file. Put this in your /etc/apache2/extra/httpd-vhosts.conf and uncomment the following line in http.conf:

...
Include /private/etc/apache2/extra/httpd-vhosts.conf

This will make apache load this virtual host configuration.

4. Error:
After login as admin, there is following error:

  file_put_contents(temporary://devel_themer/: failed to open stream: DrupalTemporaryStreamWrapper::stream_open" call failed in devel_themer_store_krumo() 

Apparently, Drupal(devel_themer module) uses local file system for storing temporary files. Make sure the temp folder for drupal got permissions to write. Go to Administration >> Configuration >> Media >> File system and look ‘Temporary Directory’ to find out where is the folder located. Afterwards, enable write permission

5. PDOException: SQLSTATE[HY000] [2002] Connection refused in lock_may_be_available() [..] includes/lock.inc drupal

This error is because Drupal unable to connect to MySQL database. You can double check your DB configurations in settings.php by connecting manually from command line as follows:

mysql -u userName -p -h hostName

Where the userName and hostName is the value from the db configuration in settings.php. Most likely, you don’t have a user with that hostname in the database. To check, run:

SELECT user FROM mysql.user;

And look for the username as well as the hostName. If it doesn’t exist then to create one:

GRANT ALL PRIVILEGES ON db_name.* TO db_user@'hostname' IDENTIFIED BY 'db_passwd';

Installing Twitter Bootstrap with Drupal

This post covers installing Twitter Bootstrap with Drupal using Drush

Tested:Drupal 7.18

Bootstrap(below 2.2) Without CDN

Step-1 Install Drupal Twitter Bootstrap Module

drush dl bootstrap-7.x-2.2
drush en bootstrap-7.x-2.2

This will create the base bootstrap theme in sites/all/themes folder

Step-2 Update with 2.3.2 Twitter Bootstrap
Downloaded the version 2.3.2 from Twitter Bootstrap and extract into sites/all/themes/bootstrap/bootstrap folder(yes, it is not mistake folder ‘bootstrap’ within folder ‘bootstrap’). Afterwards, you can test it by going in ‘Appearance’ section and setting ‘bootstrap’ as default theme to see if it works

UPDATE April, 2015:
There is no more support for CDN Bootstrap 2.3.2, so to make it work, you have to configure Bootstrap locally as follows:

  1. Disable CDN by updating bootstrap.info
    settings[cdn_bootstrap] = 0

    Or desable from the UI in the Theme/Bootstrap/Settings

  2. Specify to read Bootstrap libraries locally by including the following in bootstrap.info
    scripts[] = 'bootstrap/js/bootstrap.min.js'
    stylesheets[all][] = bootstrap/css/bootstrap.min.css
    

    Here, we assumed you have downloaded bootstrap libraries into the /bootstrap directory as described Step-2 above

Step-3 Create Your Theme
Follow steps https://drupal.org/node/1844448 to create your theme. To summarize, create your theme folder. In this folder add file themeName.info and update accordingly. At last, copy UI artifacts in the theme/css and image folder

Step-4 Converting Theme
In this process, we suggest to do one page at the time by coping template files from sites/all/themes/bootstrap/templates into sites/all/themes/yourThema/templates. This will override the base bootstrap theme templates so you can modify per your needs and it doesn’t affect future Twitter Bootstrap upgrades.

Boostrap 2.3 With CDN

With module bootstrap 7.x-2.2, the structure is different for building Drupal themes that inherits from bootstrap. It also have a setup that retrieves the Twitter Bootstrap library dynamically and doesn’t physically store library files locally. While it provides convenient way to switch between versions of Bootstrap, it does require you to depend on third party.

Step-1 Install The New Drupal Twitter Bootstrap Module

drush dl bootstrap
drush en bootstrap

To test it, login as administrator and set the default theme(admin->Appearance and click ‘Set Default’ for Bootstrap theme) to the Bootstrap theme
Step-2 Create Your New Themes Codebase
All of the themes are inherited from the Bootstrap main theme and is referred as sub-themes
a)Create Sub Theme
Make a copy of the ‘bootstrap_subtheme’ folder, rename to your new theme name and place it in ‘sites/all/themes/’ folder. By keeping it outside the Bootstrap directory it makes easy to upgrade Drupal Bootstrap module in future
b) Setup Configuration of Your New Subtheme
Rename the file ‘sites/all/themes/NEWTHEME_NAME/bootstrap_subtheme.info.starterkit’ to ‘sites/all/themes/NEWTHEME_NAME/NEWTHEME_NAME.info’
c) Configure Your New Subtheme
Update the ‘sites/all/themes/NEWTHEME_NAME/NEWTHEME_NAME.info’ file with:

name = NEWTHEME_NAME
description = description of your new NEWTHEME.
core = 7.x
base theme = bootstrap

Step-3 Enable Theme
Clear cache and go to ‘Admin/appearance’ to switch to your new theme

Run Bootstrap 3.0.x Locally

At this time, the Drupal Bootstrap module for Drupal has Boostrap 3.0.x version as other release, so to download with drush you have to specify complete version as following:

sudo drush dl bootstrap-7.x-3.0-rc2
drush en bootstrap

Afterwards, make sure you have jQuery_update module with Jquery version 1.7 or above

a)Disable CDN Loading
Go to Theme Settings(admin/appearance/settings/YOUR-THEME) and uncheck ‘use CDN load..’ under THEME CDN SETTINGS section.
Also update the ‘settings[cdn_bootstrap]’ to ‘0’ in the THEMENAME.info file to change the default setting for CDN to be disabled

b)Install Bootstrap 3.0.x Locally
From the Bootstrap site, grab the zip file and extract all artifacts(Css, Js, Font,etc) into the ‘bootstrap’ folder of your theme. This will keep Bootstrap separately easy for upgrade in future

c)Configure to load Bootstrap Library Manually
Next configure to load Bootstrap library from the local file system by adding the following in ThemeName.info file:

;Stylesheets
stylesheets[all][] = bootstrap/css/bootstrap.min.css

;JavaScript
scripts[] = 'bootstrap/js/bootstrap.min.js'

This approach gives a way to import a none minimal version by updating the name of bootstrap file ‘bootstrap.min.js’ to ‘boostrap.js’ and the same for css. Please, note that we don’t exclude bootstrap.css like boostrap.js because on Jan, 2014 the bootstrap.css is not always included like .js. It may change. Please see code ‘bootstrap/theme/alter.inc’

c)Auto load Bootstrap Library
Perhaps, you like to have so that once CDN disable it automatically grabs the local version, then you have to update ‘bootstrap/theme/alter.inc’ file as following:

function bootstrap_js_alter(&$js) {
...
// Add CDN.
  if (theme_get_setting('bootstrap_cdn')) {
    $cdn = '//netdna.bootstrapcdn.com/bootstrap/' . theme_get_setting('bootstrap_cdn')  . '/js/bootstrap.min.js';
    $js[$cdn] = drupal_js_defaults();
    $js[$cdn]['data'] = $cdn;
    $js[$cdn]['type'] = 'external';
    $js[$cdn]['every_page'] = TRUE;
    $js[$cdn]['weight'] = -100;
  }else{
      /***********ADD THESE LINES BELOW*********/
      $active_theme_path = drupal_get_path('theme', $GLOBALS['theme']);
      $cdn = '/' . $active_theme_path .'/bootstrap/js/bootstrap.min.js';
      $js[$cdn] = drupal_js_defaults();
      $js[$cdn]['data'] = $cdn;
      $js[$cdn]['type'] = 'external';
      $js[$cdn]['every_page'] = TRUE;
      $js[$cdn]['weight'] = -100;
  }
}

In line 4, it check if CDN is enable. If it is not then the local Js Bootstrap library is added. The similar change have to be made for CSS in the same file ‘bootstrap/theme/alter.inc’ as following:

function bootstrap_css_alter(&$css) {
...
if
 $bootstrap_cdn = theme_get_setting('bootstrap_cdn');
  if ($bootstrap_cdn) {
    // Add CDN.
    if (theme_get_setting('bootstrap_bootswatch')) {
      $cdn = '//netdna.bootstrapcdn.com/bootswatch/' . $bootstrap_cdn  . '/' . theme_get_setting('bootstrap_bootswatch') . '/bootstrap.min.css';
    }
    else {
      $cdn = '//netdna.bootstrapcdn.com/bootstrap/' . $bootstrap_cdn  . '/css/bootstrap.min.css';
    }
  }else{
      /********ADD THE FOLLOWING LINES***********/
      $active_theme_path = drupal_get_path('theme', $GLOBALS['theme']);
      if (theme_get_setting('bootstrap_bootswatch')) {
          $cdn =  $active_theme_path . '/bootswatch/' . theme_get_setting('bootstrap_bootswatch') . '/bootstrap.min.css';
      }
      else {
          $cdn =  '/' . $active_theme_path . '/bootstrap/css/bootstrap.min.css';
      }
  }
    $css[$cdn] = array(
      'data' => $cdn,
      'type' => 'external',
      'every_page' => TRUE,
      'media' => 'all',
      'preprocess' => FALSE,
      'group' => CSS_THEME,
      'browsers' => array('IE' => TRUE, '!IE' => TRUE),
      'weight' => -2,
    );
...
}

Here, the same way in line 5 there is a check if CDN enabled. If not, then the Bootstrap Css library attached or the Bootswatch if enabled

d) Turn Bootswatch locally
Bootswatch may be the next thing where the layout is separated out from the styling for easy swap between the styles. To get Bootswatch run locally, first clone it in some folder separate from your projeced

sudo git clone https://github.com/thomaspark/bootswatch.git bootswatch

Then, create as symbolic link from your sub-theme as following:

ln -s {/path/to/bootswatch} bootswatch

By keeping bootswatch separate, it will be easy to upgrade in future for all of the subthemes that is linking to the bootswatch

e) Load Your Custom Bootstrap
It appears that the newest version of Drupal Bootstrap grabs the local JS from the base theme Bootstrap when the CDN is disabled. Perhaps, you like to load particular version from your subfolder then it will conflict unless you disable the default local bootstrap as following in template.tpl.php:

function THEME_js_alter(&$javascript) {
    unset($javascript[drupal_get_path('theme','bootstrap').'/js/bootstrap.js']);
}
function THEME_css_alter(&$css) {
    unset($css[drupal_get_path('theme','bootstrap').'/css/bootstrap.css']);
}

This removes the Boostrap JS/CSS lib to load from the base bootstrap theme so you can load it from you sub-theme as you wish

Afterwards, configure to load in THEME.info file as following:

;stylesheets[all][] = bootstrap/css/bootstrap.min.css
stylesheets[all][] = bootswatch/amelia/bootstrap.min.css

In first linke, uncomment the original bootstrap library, so it doesn’t load. And then specify which bootstwatch to load(i.e. amelia)

Issues

1. This version is not compatible with Drupal 7.x and should be replaced.
This error was due to the fact that the theme.info file didn’t specified the Drupal version, so by adding:

core = 7.x

This solved the issue

2. My New Bootstrap Subtheme Doesn’t Style
After creating the subtheme and enabling as the current theme, the styling is not being applied. This happens, if we haven’t specified the sub theme to inherit from Bootstrap main theme. Make sure your theme.info file contains the following:

base theme = bootstrap

This tells that your subtheme inherits the Bootstrap theme.

3. TypeError: a(…).on is not a function
The following JS error is because the current jQuery Lib is not compatible with the Bootstrap. Make sure you have installed Jquery update on your Drupal site and set the jQuery version to be 1.8 or 1.7

sudo drush dl jquery_update
sudo drush en jquery_update

Afterwards, go to the Modules->jQuery Update->Configurations to set the jQuery version

4. Unable To Use Admin Controls
Once logged in, you are unable to click on any of the admin controls in top horizontal menu. This is because the top sub themes navigation horizontal region is on top of the admin controls and you cannot see it because it is transparent background. To solve the problem add the following in css/style.css file

#navbar{
    z-index: 0;
}

This moves the top horizontal menu underneath the admin controls menu.
!Make sure you are importing the styles.css file by having following entry in the themeName.info file:

...
stylesheets[all][] = css/style.css

5. IE Support
To make your bootstrap themes to work for IE8 and lower version, you have to include the Respond.js in the html as described in Bootstrap Docs. In addition, you have to ensure that your stylesheets are imported via LINK tag instead of STYLE/import. Otherwise, the Respond.js script will not provide the IE support needed. In our case, we were using drupal_add_css() function to attach the CSS styles which by default imports CSS styles via STYLE/import style. As result, the themes were not displaying properly in IE. So, to make it import styles via LINK tag:

 drupal_add_css(drupal_get_path('theme',$GLOBALS['theme']) .'/custom-bootstrap/bootstrap.min.css', array('type' => 'file','preprocess' => FALSE, 'weight' => CSS_THEME));

Here, by specifying the ‘preprocess’ option to FALSE, makes the CSS import via LINK tag(the same if type=’external’). It may not be necessary if the aggregation is turned on,then by default it imports via LINK tag