2014-01-26

Clone and Resize KVM Virtual Machine

(Up-to-date source of this post.)

I needed to upgrade (from Squeeze to Wheezy) some important virtual servers. As I wanted a minimal impact of the upgrade, I chose this procedure:

  1. Create identical copy of the server to upgrade
  2. Upgrade the copy
  3. Upgrade the server if everything worked ok with the copy

The servers to upgrade were virtual machines (VMs) running on KVM. I also discovered that some servers needed more space because their disks had filled up during upgrade. So disk resize was needed. The following steps did the task:

1) Copy the image (.qcow2) and the configuration (.xml) files to some other location. The image file should ideally be copied from a snapshot to avoid data inconsistencies a running machine could create.

2) Edit the following fields in the copied .xml file accordingly

name
uuid
source dev    # make sure you enter the copied image path!
mac address
source bridge # change the VLAN to avoid IP address conflicts

3) Boot the cloned VM and change the hostname and IP address by editing these files:

/etc/network/interfaces
/etc/hostname
/etc/hosts

4) Change back the VLAN and shutdown the cloned VM

5) Increase the disk size

# convert the qcow image to a plain raw file
qemu-img convert system.qcow -O raw system.raw
# create a dummy file (filled with zeros) of the size of extra space you want to add to your image (here 1GB)
dd if=/dev/zero of=zeros.raw bs=1024k count=1024
# add your extra space to your raw system image without fear
cat system.raw zeros.raw > big.raw
# finally convert back your raw image to a qcow file not to waste space
qemu-img convert big.raw -O qcow growed-system.qcow

6) Boot the cloned VM and using cfdisk delete the old small partition and create a new one with the free space

7) Increase the filesystem using:

e2fsck -f
resize2fs

Make sure the VM's image file (.qcow) has the correct access rights, otherwise your system might have disk related problems (I was bitten by this and got helped by my nice colleague).

2014-01-06

Simple Source Code Management with Git

(Up-to-date source of this post.)

Although I'm more of a sysadmin than a developer I often write scripts (in Perl or Bash). And I tend to use Git for tracking my programs. Every Git repository contains complete history of revisions and is not dependent on a central server or network access. I don't work within a big group of developers, so I try to keep things simple.

First time setup


The following steps are usually needed to be done only once on a machine and are global for all Git repositories:

git config --global user.name "Jeffrey Lebowski"
git config --global user.email "jeffrey.lebowski@dude.com"
git config --global color.ui true
git config alias.lol 'log --pretty=oneline --abbrev-commit --graph --decorate'
git config --global core.editor vim
git config --global merge.tool vimdiff

The I can check the configuration like this:

git config --list

or

cat ~/.gitconfig

Starting a new Git repository


One way to start working with Git is to initialize a directory as a new Git repository:

mkdir project
cd project
git init

Notice a new .git directory. Then I take the snapshot of the contents of all files within current working directory (.):

git add .    # temporary storage - index

This command adds the files to a temporary staging area called index. To permanently store the index:

git commit   # permanent storage

I enter a commit message and I'm done.

Cloning a Git repository


I often need to get an already existing repository (some code me or someone else has already written and stored for example on GitHub):

## Any server with ssh and git
git clone ssh://[user@]server.xy/path/to/repo.git/
## GitHub
git clone git://github.com/ingydotnet/....git

Working with Git


When dealing with Git, it's best to work in small bits. Rule of thumb: if you can't summarize it in a sentence, you've gone too long without committing.

My typical working cycle is:

1. Work on my project.

2. Check whether something has changed:

git status

3. Check what has changed:

git diff

4. Add and commit changes (combines two steps in one git add + git commit):

git commit -am "commit message"

If I not only changed files but also added some new ones I have to add them explicitly:

git add newfile1 newfile2 newfolder3

and then commit as in step 4.

Excluding some files


To set certain files or patterns to be ignored by Git, I create a file called .gitignore in my project’s root directory:

# Don't track dot-files
.*
!/.gitignore

.gitignore is usually checked into Git and distributed along with everything else.