how to create custom vagrant box from libvirt/kvm instance?

16,989

after spending time with vagrant i got the solution for custom box. first of all install any Linux OS in libvirt/qvm and login to it for customization and create vagrant user with password vagrant

adduser vagrant

vagrant user should be able to run sudo commands without a password prompt

sudo visudo -f /etc/sudoers.d/vagrant

and paste

vagrant ALL=(ALL) NOPASSWD:ALL

do whatever you want to customize your vagrant box and install openssh-server if not installed previously

sudo apt-get install -y openssh-server

put ssh key from vagrant user

mkdir -p /home/vagrant/.ssh
chmod 0700 /home/vagrant/.ssh
wget --no-check-certificate \
https://raw.github.com/mitchellh/vagrant/master/keys/vagrant.pub \
-O /home/vagrant/.ssh/authorized_keys
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh

open sudo vi /etc/ssh/sshd_config and change

PubKeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
PermitEmptyPasswords no
PasswordAuthentication no

restart ssh service using

 sudo service ssh restart

install additional development packages for the tools to properly compile and install

sudo apt-get install -y gcc build-essential linux-headers-server

do any change that you want and shutdown the VM . now , come to host machine on which guest VM is running and goto the /var/lib/libvirt/images/ and choose raw image in which you did the change and copy somewhere for example /test

cp /var/lib/libvirt/images/test.img  /test 

create two file metadata.json and Vagrantfile in /test do entry in metadata.json

{
  "provider"     : "libvirt",
  "format"       : "qcow2",
  "virtual_size" : 40
}

and in Vagrantfile

Vagrant.configure("2") do |config|
         config.vm.provider :libvirt do |libvirt|
         libvirt.driver = "kvm"
         libvirt.host = 'localhost'
         libvirt.uri = 'qemu:///system'
         end
config.vm.define "new" do |custombox|
         custombox.vm.box = "custombox"       
         custombox.vm.provider :libvirt do |test|
         test.memory = 1024
         test.cpus = 1
         end
         end
end

convert test.img to qcow2 format using

sudo qemu-img convert -f raw -O qcow2  test.img  ubuntu.qcow2

rename ubuntu.qcow2 to box.img

mv ubuntu.qcow2 box.img 

Note: currently,libvirt-vagrant support only qcow2 format. so , don't change the format just rename to box.img. because it takes input with name box.img by default.
create box

tar cvzf custom_box.box ./metadata.json ./Vagrantfile ./box.img 

add box to vagrant

vagrant box add --name custom custom_box.box

go to any directory where you want to initialize vagrant and run command bellow that will create Vagrant file

vagrant init custom

start configuring vagrant VM

vagrant up --provider=libvirt 

enjoy !!!

Share:
16,989

Related videos on Youtube

pl_rock
Author by

pl_rock

I am working as a Technical lead. I Like python, container , kubernetes, Open source tools, cloud, PaaS , etc.

Updated on September 18, 2022

Comments

  • pl_rock
    pl_rock over 1 year

    There are many resources on the Internet to create a custom vagrant box from a VirtualBox instance. But I want to know a direct method to create a custom vagrant box directly from a kvm/libvirt instance . Please don't suggest vagrant-mutate or any that convert VirtualBox to another provider.

  • ThorSummoner
    ThorSummoner about 7 years
    I wanted to point out, that after spending all that time tar'ing up them gigs, vagrant spends an equivalent amount of time decompressing that tar again. :fubar:
  • ThorSummoner
    ThorSummoner about 7 years
    to skip the round-trip tar/untar, you might be able to drop your Vagrantfile, meta.json, and box.img directly in ~/.vagrant.d/boxes/<name>/0/libvirt/
  • avimehenwal
    avimehenwal almost 7 years
    UPvote for so clear explanation for a relatively complicated procedure. Thanks