Category Archives: Linux OS

Using SSH to clone Git repository with multiple private keys

I prefer to use the multiple private keys and avoid using the same private key with multiple services. Recently I decided to switch from HTTPS based Git clone of my bitbucket repositories to SSH based Git clone. So created a new private key added them into bitbucket.org and then I expected that my git clone would work. But it didn’t.

git clone git@bitbucket.org:mybitbucketid/mygitrepository.git
Cloning into 'mygitrepository'...
conq: repository access denied.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

I knew I had to point the git client to my private key so I created the following entry in my ~/.ssh/config file.

Host bitbucketrepo
HostName bitbucket.org
IdentityFile ~/.ssh/bitbucket_private_key
User git

Now I felt it would work. I tried again and it still didn’t work.

git clone bitbucketrepo:mybitbucketid/mygitrepository.git
Cloning into 'mygitrepository'...
conq: repository access denied.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Now I was confused as to why it was not working. On further research I found this link. Now I updated the entry in my ~/.ssh/config file to this.

Host bitbucketrepo
HostName bitbucket.org
IdentityFile ~/.ssh/bitbucket_private_key
IdentitiesOnly yes
User git

Now I tried again. This time it worked perfectly.

git clone bitbucketrepo:mybitbucketid/mygitrepository.git
Cloning into 'mygitrepository'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.

Well the addition of “IdentitiesOnly yes” line in my config file did the trick. It seems that when we do an SSH connection it’s default behavior is to send the identity file matching the default filename for each protocol. So if you have a file named ~/.ssh/id_rsa then that will get tried before your private key which in my case was ~/.ssh/bitbucket_private_key. So by using the “IdentitiesOnly yes” line I explicitly asked my ssh client to use my identity file and nothing else and it worked like a charm.

Awesome tmux

I have always found moving between tabbed interfaces cumbersome in my Mac terminal. Finally when debugging 7 different log files sitting on 7 different servers I felt enough was enough and started looking for a solution. Enter ‘tmux’.

tmux is a terminal multiplexer which supports multiple windows inside a single terminal session and allows me to create horizontal as well as vertical panes. So I can debug the logs sitting on different servers by tailing them in different pane and then still can have one pane dedicated for executing commands. I found a very good tutorial at this and this location.

Now I don’t want to go back to the old way of having multiple tabs for multiple logs. Agreed tabs in terminal have their own place and usage but for this particular case where I am doing development and debugging multiple servers I don’t have time for a tabbed interface instead ‘tmux’ is the way to go.

Searching for file containing keyword in Linux

Grep suits the bill for all my requirement for efficient search of files containing text in Linux and Mac. The following commands detail the use cases of grep.

Search for pattern
grep -rnw 'folder' -e 'text'

-r stands for recursive.
-n is the line number.
-w stands for whole word match.

Example: grep -rnw . -e 'import'
This searches for the the text ‘import’ in the current directory recursively.

Found this tip at stackoverflow.com.

Using grep, sed to filter data in Linux, Mac OS

I recently received a blob of data which needed some alteration to properly suit the CSV format. I found that the data file ‘xyz.dat’ contained close to 600,000 rows so writing a VBA script in Excel to format the data was not an option. I opted to do it using some plain commands in Unix. I had to attain the following purpose:

1. Remove all rows with blank lines.
2. Remove all rows that didn’t start with the number ‘1’
3. Trim the file to 1000 rows to sample the data.

I executed the following commands to attain the above objectives.

To remove all blank lines I used this command. I am basically asking grep to treat the text as ASCII text and using a regular expression to identify blank rows:
cat xyz.dat | grep -a -v -e '^[[:space:]]*$' > xyz_no_space.dat

To remove all rows that don’t start with ‘1’ I used this command. This command is similar to above command except for the regular expression to identify rows that start with ‘1’.
cat xyz_no_space.dat | grep -a '^1' > xyz_no_space_start_with_1.dat

At this point we have the data we want but for sampling purpose I need to copy first 1000 rows into another file. This command uses ‘sed’ to do it.
sed -n -e '1,1000p' xyz_no_space_start_with_1.dat > xyz_trimmed_1_1000.dat

This command basically renames the *.dat file into *.csv for convenience.
mv xyz_trimmed_1_1000.dat xyz_trimmed_1_1000.csv

A summary of all commands I executed is listed below:
cat xyz.dat | grep -a -v -e '^[[:space:]]*$' > xyz_no_space.dat
cat xyz_no_space.dat | grep -a '^1' > xyz_no_space_start_with_1.dat
sed -n -e '1,1000p' xyz_no_space_start_with_1.dat > xyz_trimmed_1_1000.dat
mv xyz_trimmed_1_1000.dat xyz_trimmed_1_1000.csv

Integrating Jenkins (Debian) with BitBucket

The Jenkins CI server can be integrated with BitBucket by using the concept of deployment keys. In BitBucket go to Settings > Deployment Keys. Add a new public key. Make sure you are adding an openssh compatible public key otherwise the key won’t be accepted. Once this is done you need to test the read-only cloning capability using this approach.

ssh-agent (ssh-add /home/user1/ssh_keys/my_private_key; git clone git@bitbucket.org:my_user/my_project.git)

This command basically attempts to make a clone from the BitBucket server using the private key you specified as ‘my_private_key’. Since we are using the ssh-agent command to wrap the other two commands the key is loaded, the clone command is executed and then immediately the key is unloaded. If your cloning process failed you know that something is wrong. Remember you need the private key in openssh format as well.

If the above command gave you the cloned repository, go ahead and use this private key inside the Jenkins server.

Please do refer to BitBucket documentation link has more details on the exact steps.

Jenkins Configuration Issue

I was trying to setup Jenkins web app inside the Tomcat server and it continuously gave me this error:

SEVERE: Failed to initialize Jenkins
hudson.util.NoHomeDir

This I fixed by creating the folder ‘/usr/share/tomcat7/.jenkins’

mkdir /usr/share/tomcat7/.jenkins

On redeploying Jenkins I again noticed the following error.

WARNING: Failed to record boot attempts
java.io.FileNotFoundException: /usr/share/tomcat7/.jenkins/failed-boot-attempts.txt (Permission denied)

I fixed this issue by giving full access to this folder.

sudo chmod 777 /usr/share/tomcat7/.jenkins

I believe 777 is not a good approach in a production environment, but for development perspective it looks ok.