In this blog post, I’m going to explain how to safely move a Vagrant Box from one location on your to another on your Linux machine (Originally published on Medium.com, 27-Nov-2018)
Lately, I found myself building a CI/CD infrastructure using Vagrant. If this the first time you work with Vagrant, just like it was for me, you can also find my Introduction to Vagrant article, to get yourself up-to-speed.
During the development process, I found myself re-designing my solution multiple times as requirements evolved and the infrastructure grew and became more complex.
In this article I will discuss one of the more esoteric tasks I stumbled upon: Moving an existing Vagrant environment that uses VirtualBox as a provider from one directory to the other. One of the steps when preparing one of the environments took many hours, and I couldn’t afford myself starting the process from scratch every time, so instead, I had to break the laws of thermodynamics and hack my way into moving existing environments. If you know what to do, it’s very easy, so hopefully this will save you some time.
Disclaimer: This guide comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law.
For this example, I’ll assume we have a single Vagrant environment on our host machine, called ubuntu16
located under /home/user/VMs/ubuntu16
and we would like to move it to /vagrant_vms/ubuntu16
.
Before doing anything, let’s call vagrant global-status
from anywhere on the host machine. The output should look like this:
user@laptop:~/Documents$ vagrant global-status id name provider state directory ------------------------------------------------------------- a64fcec default virtualbox running /home/user/VMs/ubuntu16 The above shows information about all known Vagrant environments on this machine. This data is cached and may not be completely up-to-date (use "vagrant global-status --prune" to prune invalid entries). 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"
We can see our environment in bold right in the middle with all the relevant details. Our indication for success will be Vagrant’s acknowledgment of the new location. So, let’s begin:
Step 1: Power off the Vagrant environment
Enter the environment’s directory (Which is /VMs/ubuntu16
in our case) and execute Vagrant halt
to shut it down.
Step 2: Move the Vagrant environment
Make sure that the target parent directory already exists, so that the move operation succeeds:
mkdir /vagrant_vms
Move the environment to the new location using the following command:
mv /VMs/ubuntu16 /vagrant_vms
Step 3: Update Vagrant’s index file
Vagrant keeps the index at ~/.vagrant.d/data/machine-index/index
using JSON format. First, let’s examine the file contents comfortably by using the following command:
python -m json.tool ~/.vagrant.d/data/machine-index/index
NOTE: This command uses Python’s JSON tools. If you don’t have one installed, just open the same file using your favorite text editor, e.g. vim
.
The output should be similar to this:
{
"machines": {
"00e03d75df75445b927feade8a1ea56c": {
"extra_data": {
"box": {
"name": "ubuntu/xenial64",
"provider": "virtualbox",
"version": "0"
}
},
"local_data_path": "/home/user/VMs/ubuntu16/.vagrant",
"name": "default",
"provider": "virtualbox",
"state": "poweroff",
"updated_at": null,
"vagrantfile_name": null,
"vagrantfile_path": "/home/user/VMs/ubuntu16"
}
},
"version": 1
}
As we can see, there are two values here we need to change. So let’s open the file using our favorite text editor and update the content:
local_data_path
values should be set to/vagrant_vms/ubuntu16/.vagrant
vagarantfile_path
should be set to/vagrant_vms/ubuntu16
Step 4: Update the environment
Each Vagrant environment has two more additional index files it uses to store such configuration. We’ll edit those as well. By now, our environment is already at its new location, so we’ll enter the new environment directory: /vagrant_vms/ubuntu16/.vagrant/machines/default/virtualbox/
First, lets update vagrant_cwd
and set the value to /vagrant_vms/ubuntu16
Second, if you configured any shared directories between the guest and the host, we have to update the synced_folders
file. Every instance of /home/user/VMs/ubuntu16
should be replaced by /vagrant_vms/ubuntu16
.
That was actually it. Right now, if you run the vagrant global-status --prune
command (prune is require to update the internal index), you should see the new location for your environment. You can now once again use your environment to hack the Pentagon or try and install your Backend application for the 32nd time.
Enjoyed this guide? Check out other stuff I write about productivity tools, system internals and software in general. Might even wanna subscribe to my newsletter.