Destroying all your Vagrant Boxes

Destroying all your Vagrant Boxes

TLDR;

for vb in `vagrant global-status | grep virtualbox | awk '{ print $1 }'` ; do vagrant destroy $vb ; done

I've been playing around with Vagrant a lot recently and in doing so I've ended up with lots of unused vagrant boxes on my machine. I could go and delete them all individually but it seemed a good oppertunity to learn some scripting.

Stage One - Finding all the Vagrant Boxes

Vagrant has a command that allows you to list all the vagrant machines currently on your computer, vagrant global-status:

$ vagrant global-status
id       name   provider   state   directory
-------------------------------------------------------------------------------
1e4d043  acs    virtualbox running /Users/mat-mcloughlin/git/ansi...
2c876e3  web    virtualbox running /Users/mat-mcloughlin/git/ansi...
63d6ed7  db     virtualbox running /Users/mat-mcloughlin/git/ansi...
5844cda  ghost  virtualbox running /Users/mat-mcloughlin/git/ghos...
92ce8ce  ghost  virtualbox running /Users/mat-mcloughlin/temp
3d06166  ghost  virtualbox running /Users/mat-mcloughlin/git/ghos...

The above shows information about all known Vagrant environments
on this machine. This data is cached and may not be completely
up-to-date. To interact with any of the machines, you can go to
that directory and run Vagrant, or you can use the ID directly
with Vagrant commands from any directory. For example:
"vagrant destroy 1a2b3c4d"

As the command says this data is cached and isn't guaranteed to be up to date but it's the best we've got.

The important part of this response is the id column as thats what we are going to use to delete the boxes. However, in its current state its useless so we need to manipulate it into a single collection of ID's.

Stage Two - Getting a list of Vagrant IDs

The next step is to strip away all of the response text with the exception of the lines that contain the ID's.

This can been done using a tool called grep. grep is a powerful tool that can be used to search for lines containing a match within given input. You can use regular expressions and a number of different options such as --ignore-case to be more precise but in our case we just need to find lines that contain the text "virtualbox":

grep virtualbox

To use grep on the output of the previous vagrant command we need to "pipe" it in. This is done by using the | command:

$ vagrant global-status | grep virtualbox
1e4d043  acs    virtualbox running /Users/mat-mcloughlin/git/ansi...
2c876e3  web    virtualbox running /Users/mat-mcloughlin/git/ansi...
63d6ed7  db     virtualbox running /Users/mat-mcloughlin/git/ansi...
5844cda  ghost  virtualbox running /Users/mat-mcloughlin/git/ghos...
92ce8ce  ghost  virtualbox running /Users/mat-mcloughlin/temp
3d06166  ghost  virtualbox running /Users/mat-mcloughlin/git/ghos...

The | command simply takes the output of one command and sends it into the next.

The next next step is to remove everything from these lines except for the IDs. For this we can use a tool called awk for this. AWK is a programming language typically used for text manipulation or extraction so it's perfect for extracting first symbol from each line. We do this by telling it to "print" the first word of each line:

awk '{ print $1 }'

Again piping the contents of the grep command in gives us this:

$ vagrant global-status | grep virtualbox | awk '{ print $1 }'
1e4d043
2c876e3
63d6ed7
5844cda
92ce8ce
3d06166

And there we have it a list of the IDs. The next step is to iterate through each of these and delete the box

Stage Three - Iterating the IDs

Bash and ZSH both allow you use a for loop to iterate through a list of items with the following construct:

for i in `<somelist>` ; do <somecommand> $i ; done

Where $i is the iterator and we can use this to iterate through each of the Ids in our list and call the vagrant destroy command:

$ for vb in `vagrant global-status | grep virtualbox | awk '{ print $1 }'` ; do vagrant destroy $vb ; done
    acs: Are you sure you want to destroy the 'acs' VM? [y/N] y
==> acs: Destroying VM and associated drives...
    web: Are you sure you want to destroy the 'web' VM? [y/N] y
==> web: Destroying VM and associated drives...
    db: Are you sure you want to destroy the 'db' VM? [y/N] y
==> db: Destroying VM and associated drives...
    ghost: Are you sure you want to destroy the 'ghost' VM? [y/N] y
==> ghost: Destroying VM and associated drives...
    ghost: Are you sure you want to destroy the 'ghost' VM? [y/N] y
==> ghost: Forcing shutdown of VM...
==> ghost: Destroying VM and associated drives...

And thats it. All Your Vagrant boxes have been destroyed. If you don't want to confirm each box at a time you can pass the -f argument in when calling vagrant destroy.

Comments