[DRE-commits] [vagrant-libvirt] 01/04: Imported Upstream version 0.0.31

Antonio Terceiro terceiro at moszumanska.debian.org
Mon Oct 5 02:00:21 UTC 2015


This is an automated email from the git hooks/post-receive script.

terceiro pushed a commit to branch master
in repository vagrant-libvirt.

commit 755cb0ca8e9a6fe542fe36f8087b1525a8f0d00b
Author: Antonio Terceiro <terceiro at debian.org>
Date:   Sun Oct 4 22:49:40 2015 -0300

    Imported Upstream version 0.0.31
---
 .travis.yml                                        |  20 +++
 Gemfile                                            |   7 +-
 README.md                                          | 152 +++++++++++++++++++-
 example_box/Vagrantfile                            |   2 +-
 example_box/metadata.json                          |   2 +-
 lib/vagrant-libvirt.rb                             |  18 +--
 lib/vagrant-libvirt/action.rb                      | 132 ++++++++----------
 lib/vagrant-libvirt/action/connect_libvirt.rb      |  51 -------
 lib/vagrant-libvirt/action/create_domain.rb        |  66 ++++++---
 lib/vagrant-libvirt/action/create_domain_volume.rb |  10 +-
 .../action/create_network_interfaces.rb            | 118 +++++++++++-----
 lib/vagrant-libvirt/action/create_networks.rb      | 153 +++++++++++++--------
 lib/vagrant-libvirt/action/destroy_domain.rb       |   8 +-
 lib/vagrant-libvirt/action/destroy_networks.rb     |   4 +-
 lib/vagrant-libvirt/action/halt_domain.rb          |   2 +-
 lib/vagrant-libvirt/action/handle_box_image.rb     |  30 +++-
 lib/vagrant-libvirt/action/handle_storage_pool.rb  |  16 ++-
 lib/vagrant-libvirt/action/is_running.rb           |   2 +-
 lib/vagrant-libvirt/action/is_suspended.rb         |   2 +-
 lib/vagrant-libvirt/action/package_domain.rb       |   6 +-
 lib/vagrant-libvirt/action/prepare_nfs_settings.rb |  13 +-
 .../action/prepare_nfs_valid_ids.rb                |   2 +-
 lib/vagrant-libvirt/action/prune_nfs_exports.rb    |   2 +-
 lib/vagrant-libvirt/action/read_mac_addresses.rb   |   2 +-
 lib/vagrant-libvirt/action/read_ssh_info.rb        |  68 ---------
 lib/vagrant-libvirt/action/read_state.rb           |  60 --------
 lib/vagrant-libvirt/action/remove_libvirt_image.rb |   2 +-
 lib/vagrant-libvirt/action/remove_stale_volume.rb  |   4 +-
 lib/vagrant-libvirt/action/resume_domain.rb        |   2 +-
 lib/vagrant-libvirt/action/set_boot_order.rb       |  66 +++++++++
 lib/vagrant-libvirt/action/set_name_of_domain.rb   |   5 +-
 lib/vagrant-libvirt/action/start_domain.rb         |   2 +-
 lib/vagrant-libvirt/action/suspend_domain.rb       |   2 +-
 lib/vagrant-libvirt/action/wait_till_up.rb         |   2 +-
 lib/vagrant-libvirt/cap/mount_p9.rb                |   3 +-
 lib/vagrant-libvirt/cap/synced_folder.rb           |  16 ++-
 lib/vagrant-libvirt/config.rb                      |  49 ++++++-
 lib/vagrant-libvirt/driver.rb                      | 121 ++++++++++++++++
 lib/vagrant-libvirt/errors.rb                      |   4 +
 lib/vagrant-libvirt/plugin.rb                      |  12 +-
 lib/vagrant-libvirt/provider.rb                    |  66 +++++++--
 lib/vagrant-libvirt/templates/domain.xml.erb       |  30 ++--
 lib/vagrant-libvirt/templates/filesystem.xml.erb   |   2 +-
 .../templates/tunnel_interface.xml.erb             |  11 ++
 lib/vagrant-libvirt/util/network_util.rb           |  12 +-
 lib/vagrant-libvirt/version.rb                     |   2 +-
 locales/en.yml                                     |  39 ++++--
 metadata.yml                                       |  11 +-
 spec/support/environment_helper.rb                 |   2 +-
 tools/prepare_redhat_for_box.sh                    |   3 +-
 50 files changed, 919 insertions(+), 497 deletions(-)

diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..f967fdf
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,20 @@
+---
+language: ruby
+before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -y libvirt-dev
+  - gem install bundler --version $BUNDLER_VERSION
+install: bundle _${BUNDLER_VERSION}_ install
+script: bundle _${BUNDLER_VERSION}_ exec rspec --color --format documentation
+notifications:
+  email: false
+rvm:
+  - 2.0.0
+env:
+  global:
+    - NOKOGIRI_USE_SYSTEM_LIBRARIES=true
+  matrix:
+    - VAGRANT_VERSION=v1.5.4 BUNDLER_VERSION=1.5.3
+    - VAGRANT_VERSION=v1.6.5 BUNDLER_VERSION=1.6.9
+    - VAGRANT_VERSION=v1.7.0 BUNDLER_VERSION=1.7.9
+    - VAGRANT_VERSION=       BUNDLER_VERSION=1.7.9
diff --git a/Gemfile b/Gemfile
index c93c514..4e4fd9d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,7 +7,12 @@ group :development do
   # We depend on Vagrant for development, but we don't add it as a
   # gem dependency because we expect to be installed within the
   # Vagrant environment itself using `vagrant plugin`.
-  gem 'vagrant', :git => 'https://github.com/mitchellh/vagrant.git'
+  if ENV['VAGRANT_VERSION']
+    gem 'vagrant', :git => 'https://github.com/mitchellh/vagrant.git',
+      tag: ENV['VAGRANT_VERSION']
+  else
+    gem 'vagrant', :git => 'https://github.com/mitchellh/vagrant.git'
+  end
   gem 'pry'
 end
 
diff --git a/README.md b/README.md
index 6e8bd19..39a45db 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,35 @@ control and provision machines via Libvirt toolkit.
 **Note:** Actual version is still a development one. Feedback is
 welcome and can help a lot :-)
 
+- [Features](#)
+- [Future work](#)
+- [Installation](#)
+  - [Possible problems with plugin installation on Linux](#)
+- [Vagrant Project Preparation](#)
+  - [Add Box](#)
+  - [Create Vagrantfile](#)
+  - [Start VM](#)
+  - [How Project Is Created](#)
+  - [Libvirt Configuration](#)
+  - [Provider Options](#)
+  - [Domain Specific Options](#)
+- [Networks](#)
+  - [Private Network Options](#)
+  - [Public Network Options](#)
+  - [Management Network](#)
+- [Additional Disks](#)
+- [CDROMs](#)
+- [Input](#)
+- [No box and PXE boot](#)
+- [SSH Access To VM](#)
+- [Forwarded Ports](#)
+- [Synced Folders](#)
+- [Customized Graphics](#)
+- [Box Format](#)
+- [Create Box](#)
+- [Development](#)
+- [Contributing](#)
+
 ## Features
 
 * Control local Libvirt hypervisors.
@@ -22,6 +51,7 @@ welcome and can help a lot :-)
 * Snapshots via [sahara](https://github.com/jedi4ever/sahara).
 * Package caching via [vagrant-cachier](http://fgrehm.viewdocs.io/vagrant-cachier/).
 * Use boxes from other Vagrant providers via [vagrant-mutate](https://github.com/sciurus/vagrant-mutate).
+* Support VMs with no box for PXE boot purposes (Vagrant 1.6 and up)
 
 ## Future work
 
@@ -155,7 +185,8 @@ end
 * `memory` - Amount of memory in MBytes. Defaults to 512 if not set.
 * `cpus` - Number of virtual cpus. Defaults to 1 if not set.
 * `nested` - [Enable nested virtualization](https://github.com/torvalds/linux/blob/master/Documentation/virtual/kvm/nested-vmx.txt). Default is false.
-* `cpu_mode` - What cpu mode to use for nested virtualization. Defaults to 'host-model' if not set.
+* `cpu_mode` - [What cpu type to emulate](https://libvirt.org/formatdomain.html#elementsCPU). Defaults to 'host-model' if not set. Allowed values: host-model, host-passthrough.
+* `loader` - Sets path to custom UEFI loader.
 * `volume_cache` - Controls the cache mechanism. Possible values are "default", "none", "writethrough", "writeback", "directsync" and "unsafe". [See driver->cache in libvirt documentation](http://libvirt.org/formatdomain.html#elementsDisks).
 * `kernel` - To launch the guest with a kernel residing on host filesystems. Equivalent to qemu `-kernel`.
 * `initrd` - To specify the initramfs/initrd to use for the guest. Equivalent to qemu `-initrd`.
@@ -170,7 +201,9 @@ end
 * `video_vram` - Used by some graphics card types to vary the amount of RAM dedicated to video.  Defaults to 9216.
 * `machine` - Sets machine type. Equivalent to qemu `-machine`. Use `qemu-system-x86_64 -machine help` to get a list of supported machines.
 * `machine_arch` - Sets machine architecture. This helps libvirt to determine the correct emulator type. Possible values depend on your version of qemu. For possible values, see which emulator executable `qemu-system-*` your system provides. Common examples are `aarch64`, `alpha`, `arm`, `cris`, `i386`, `lm32`, `m68k`, `microblaze`, `microblazeel`, `mips`, `mips64`, `mips64el`, `mipsel`, `moxie`, `or32`, `ppc`, `ppc64`, `ppcemb`, `s390x`, `sh4`, `sh4eb`, `sparc`, `sparc64`, `tricore`, `u [...]
-* `boot` - Change the boot order and enables the boot menu. Possible options are "hd" or "network". Defaults to "hd" with boot menu disabled.
+* `machine_virtual_size` - Sets the disk size in GB for the machine overriding the default specified in the box. Allows boxes to defined with a minimal size disk by default and to be grown to a larger size at creation time. Will ignore sizes smaller than the size specified by the box metadata. Note that currently there is no support for automatically resizing the filesystem to take advantage of the larger disk.
+* `boot` - Change the boot order and enables the boot menu. Possible options are "hd", "network", "cdrom". Defaults to "hd" with boot menu disabled. When "network" is set without "hd", only all NICs will be tried; see below for more detail.
+* `nic_adapter_count` - Defaults to '8'. Only use case for increasing this count is for VMs that virtualize switches such as Cumulus Linux. Max value for Cumulus Linux VMs is 33.
 
 
 Specific domain settings can be set for each domain separately in multi-VM
@@ -194,7 +227,8 @@ Vagrant.configure("2") do |config|
 
 The following example shows part of a Vagrantfile that enables the VM to
 boot from a network interface first and a hard disk second. This could be
-used to run VMs that are meant to be a PXE booted machines.
+used to run VMs that are meant to be a PXE booted machines. Be aware that
+if `hd` is not specified as a boot option, it will never be tried.
 
 ```ruby
 Vagrant.configure("2") do |config|
@@ -212,7 +246,16 @@ Vagrant.configure("2") do |config|
 ## Networks
 
 Networking features in the form of `config.vm.network` support private networks
-concept.
+concept. It supports both the virtual network switch routing types and the point to
+point Guest OS to Guest OS setting using UDP/Mcast/TCP tunnel interfaces.
+
+http://wiki.libvirt.org/page/VirtualNetworking
+
+https://libvirt.org/formatdomain.html#elementsNICSTCP
+
+http://libvirt.org/formatdomain.html#elementsNICSMulticast
+
+http://libvirt.org/formatdomain.html#elementsNICSUDP _(in libvirt v1.2.20 and higher)_
 
 Public Network interfaces are currently implemented using the macvtap driver. The macvtap
 driver is only available with the Linux Kernel version >= 2.6.24. See the following libvirt
@@ -220,14 +263,33 @@ documentation for the details of the macvtap usage.
 
 http://www.libvirt.org/formatdomain.html#elementsNICSDirect
 
+
 An examples of network interface definitions:
 
 ```ruby
-  # Private network
+  # Private network using virtual network switching
   config.vm.define :test_vm1 do |test_vm1|
     test_vm1.vm.network :private_network, :ip => "10.20.30.40"
   end
 
+  # Private network. Point to Point between 2 Guest OS using a TCP tunnel
+  # Guest 1
+  config.vm.define :test_vm1 do |test_vm1|
+    test_vm1.vm.network :private_network,
+          :libvirt__tunnel_type => 'server',
+          # default is 127.0.0.1 if omitted
+          # :libvirt__tunnel_ip => '127.0.0.1',
+          :libvirt__tunnel_port => '11111'
+
+  # Guest 2
+  config.vm.define :test_vm2 do |test_vm2|
+    test_vm2.vm.network :private_network,
+          :libvirt__tunnel_type => 'client',
+          # default is 127.0.0.1 if omitted
+          # :libvirt__tunnel_ip => '127.0.0.1',
+          :libvirt__tunnel_port => '11111'
+
+
   # Public Network
   config.vm.define :test_vm1 do |test_vm1|
     test_vm1.vm.network :public_network,
@@ -289,9 +351,29 @@ starts with 'libvirt__' string. Here is a list of those options:
 * `:libvirt__forward_device` - Name of interface/device, where network should
   be forwarded (NATed or routed). Used only when creating new network. By
   default, all physical interfaces are used.
+* `:libvirt__tunnel_type` - Set to 'udp' if using UDP unicast tunnel mode (libvirt v1.2.20 or higher).
+  Set this to either "server" or "client" for tcp tunneling. Set this to 'mcast' if using multicast
+  tunneling. This configuration type uses tunnels to
+  generate point to point connections between Guests. Useful for Switch VMs like
+  Cumulus Linux. No virtual switch setting like "libvirt__network_name" applies with
+  tunnel interfaces and will be ignored if configured.
+* `:libvirt__tunnel_ip` - Sets the source IP of the libvirt tunnel interface. By
+  default this is `127.0.0.1` for TCP and UDP tunnels and `239.255.1.1` for Multicast
+  tunnels. It populates the address field in the `<source address="XXX">` of the
+  interface xml configuration.
+* `:libvirt__tunnel_port` - Sets the source port the tcp/udp/mcast tunnel
+    with use. This port information is placed in the `<source port=XXX/>` section of
+    interface xml configuration.
+* `:libvirt__tunnel_local_port` - Sets the local port used by the udp tunnel
+    interface type. It populates the port field in the `<local port=XXX">` section of the
+    interface xml configuration. _(This feature only works in libvirt 1.2.20 and higher)_
+* `:libvirt__tunnel_local_ip` - Sets the local IP used by the udp tunnel
+    interface type. It populates the ip entry of the `<local address=XXX">` section of
+    the interface xml configuration. _(This feature only works in libvirt 1.2.20 and higher)_
 * `:mac` - MAC address for the interface.
 * `:model_type` - parameter specifies the model of the network adapter when you create a domain value by default virtio KVM believe possible values, see the documentation for libvirt
 
+
 When the option `:libvirt__dhcp_enabled` is to to 'false' it shouldn't matter
 whether the virtual network contains a DHCP server or not and vagrant-libvirt
 should not fail on it. The only situation where vagrant-libvirt should fail
@@ -336,7 +418,7 @@ You can create and attach additional disks to a VM via `libvirt.storage :file`.
 * `type` - Type of disk image to create. Defaults to *qcow2*.
 * `bus` - Type of bus to connect device to. Defaults to *virtio*.
 * `cache` - Cache mode to use, e.g. `none`, `writeback`, `writethrough` (see the [libvirt documentation for possible values](http://libvirt.org/formatdomain.html#elementsDisks) or [here](https://www.suse.com/documentation/sles11/book_kvm/data/sect1_chapter_book_kvm.html) for a fuller explanation). Defaults to *default*.
-* `allow_existing` - Set to true if you want to allow the VM to use a pre-existing disk.  This is useful for sharing disks between VMs, e.g. in order to simulate shared SAN storage. Shared disks removed only manualy.If not exists - will created. If exists - using existed.
+* `allow_existing` - Set to true if you want to allow the VM to use a pre-existing disk.  This is useful for sharing disks between VMs, e.g. in order to simulate shared SAN storage. Shared disks removed only manually. If not exists - will created. If exists - using existed.
 
 The following example creates two additional disks.
 
@@ -369,6 +451,64 @@ Vagrant.configure("2") do |config|
 end
 ```
 
+## Input
+
+You can specify multiple inputs to the VM via `libvirt.input`. Available options are
+listed below. Note that both options are required:
+
+* `type` - The type of the input
+* `bus` - The bust of the input
+
+```ruby
+Vagrant.configure("2") do |config|
+  config.vm.provider :libvirt do |libvirt|
+    # this is the default
+    # libvirt.input :type => "mouse", :bus => "ps2"
+
+    # very useful when having mouse issues when viewing VM via VNC
+    libvirt.input :type => "tablet", :bus => "usb"
+  end
+end
+```
+
+## No box and PXE boot
+
+There is support for PXE booting VMs with no disks as well as PXE booting VMs with blank disks. There are some limitations:
+
+* Requires Vagrant 1.6.0 or newer
+* No provisioning scripts are ran
+* No network configuration is being applied to the VM
+* No SSH connection can be made
+* ```vagrant halt``` will only work cleanly if the VM handles ACPI shutdown signals
+
+In short, VMs without a box can be created, halted and destroyed but all other functionality cannot be used.
+
+An example for a PXE booted VM with no disks whatsoever:
+
+```ruby
+Vagrant.configure("2") do |config|
+  config.vm.define :pxeclient do |pxeclient|
+    pxeclient.vm.provider :libvirt do |domain|
+      domain.boot 'network'
+    end
+  end
+end
+```
+
+And an example for a PXE booted VM with no box but a blank disk which will boot from this HD if the NICs fail to PXE boot:
+
+```ruby
+Vagrant.configure("2") do |config|
+  config.vm.define :pxeclient do |pxeclient|
+    pxeclient.vm.provider :libvirt do |domain|
+      domain.storage :file, :size => '100G', :type => 'qcow2'
+      domain.boot 'network'
+      domain.boot 'hd'
+    end
+  end
+end
+```
+
 ## SSH Access To VM
 
 vagrant-libvirt supports vagrant's [standard ssh settings](https://docs.vagrantup.com/v2/vagrantfile/ssh_settings.html).
diff --git a/example_box/Vagrantfile b/example_box/Vagrantfile
index 8403c87..a34b797 100644
--- a/example_box/Vagrantfile
+++ b/example_box/Vagrantfile
@@ -39,7 +39,7 @@ Vagrant.configure("2") do |config|
     libvirt.driver = "kvm"
 
     # The name of the server, where libvirtd is running.
-    libvirt.host = "localhost"
+    # libvirt.host = "localhost"
 
     # If use ssh tunnel to connect to Libvirt.
     libvirt.connect_via_ssh = false
diff --git a/example_box/metadata.json b/example_box/metadata.json
index 1cefe8f..f483ad2 100644
--- a/example_box/metadata.json
+++ b/example_box/metadata.json
@@ -1,5 +1,5 @@
 {
   "provider"     : "libvirt",
   "format"       : "qcow2",
-  "virtual_size" : 40
+  "virtual_size" : 16 
 }
diff --git a/lib/vagrant-libvirt.rb b/lib/vagrant-libvirt.rb
index 825e5fa..6118d71 100644
--- a/lib/vagrant-libvirt.rb
+++ b/lib/vagrant-libvirt.rb
@@ -1,5 +1,4 @@
 require 'pathname'
-require 'vagrant-libvirt/plugin'
 
 module VagrantPlugins
   module ProviderLibvirt
@@ -8,22 +7,11 @@ module VagrantPlugins
     autoload :Errors, lib_path.join('errors')
     autoload :Util, lib_path.join('util')
 
-    # Hold connection handler so there is no need to connect more times than
-    # one. This can be annoying when there are more machines to create, or when
-    # doing state action first and then some other.
-    #
-    # TODO Don't sure if this is the best solution
-    @@libvirt_connection = nil
-    def self.libvirt_connection
-      @@libvirt_connection
-    end
-
-    def self.libvirt_connection=(conn)
-      @@libvirt_connection = conn
-    end
-
     def self.source_root
       @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
     end
   end
 end
+
+# make sure base module class defined before loading plugin
+require 'vagrant-libvirt/plugin'
diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb
index 48f1605..dc89122 100644
--- a/lib/vagrant-libvirt/action.rb
+++ b/lib/vagrant-libvirt/action.rb
@@ -19,32 +19,40 @@ module VagrantPlugins
       def self.action_up
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
-          b.use ConnectLibvirt
           b.use Call, IsCreated do |env, b2|
             # Create VM if not yet created.
             if !env[:result]
               b2.use SetNameOfDomain
-              b2.use HandleStoragePool
-              b2.use HandleBox
-              b2.use HandleBoxImage
-              b2.use CreateDomainVolume
-              b2.use CreateDomain
-
-              b2.use Provision
-              b2.use PrepareNFSValidIds
-              b2.use SyncedFolderCleanup
-              b2.use SyncedFolders
-              b2.use PrepareNFSSettings
-              b2.use ShareFolders
-              b2.use CreateNetworks
-              b2.use CreateNetworkInterfaces
-
-              b2.use StartDomain
-              b2.use WaitTillUp
-
-              b2.use ForwardPorts
-              b2.use SetHostname
-              # b2.use SyncFolders
+              if !env[:machine].box
+                b2.use CreateDomain
+                b2.use CreateNetworks
+                b2.use CreateNetworkInterfaces
+                b2.use SetBootOrder
+                b2.use StartDomain
+              else
+                b2.use HandleStoragePool
+                b2.use HandleBox
+                b2.use HandleBoxImage
+                b2.use CreateDomainVolume
+                b2.use CreateDomain
+
+                b2.use Provision
+                b2.use PrepareNFSValidIds
+                b2.use SyncedFolderCleanup
+                b2.use SyncedFolders
+                b2.use PrepareNFSSettings
+                b2.use ShareFolders
+                b2.use CreateNetworks
+                b2.use CreateNetworkInterfaces
+                b2.use SetBootOrder
+
+                b2.use StartDomain
+                b2.use WaitTillUp
+
+                b2.use ForwardPorts
+                b2.use SetHostname
+                # b2.use SyncFolders
+              end
             else
               b2.use action_start
             end
@@ -58,7 +66,6 @@ module VagrantPlugins
       def self.action_start
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
-          b.use ConnectLibvirt
           b.use Call, IsRunning do |env, b2|
             # If the VM is running, then our work here is done, exit
             next if env[:result]
@@ -70,27 +77,35 @@ module VagrantPlugins
                 next
               end
 
-              # VM is not running or suspended.
+              if !env[:machine].box
+                # With no box, we just care about network creation and starting it
+                b3.use CreateNetworks
+                b3.use SetBootOrder
+                b3.use StartDomain
+              else
+                # VM is not running or suspended.
 
-              b3.use Provision
+                b3.use Provision
 
-              # Ensure networks are created and active
-              b3.use CreateNetworks
+                # Ensure networks are created and active
+                b3.use CreateNetworks
+                b3.use SetBootOrder
 
-              b3.use PrepareNFSValidIds
-              b3.use SyncedFolderCleanup
-              b3.use SyncedFolders
+                b3.use PrepareNFSValidIds
+                b3.use SyncedFolderCleanup
+                b3.use SyncedFolders
 
-              # Start it..
-              b3.use StartDomain
+                # Start it..
+                b3.use StartDomain
 
-              # Machine should gain IP address when comming up,
-              # so wait for dhcp lease and store IP into machines data_dir.
-              b3.use WaitTillUp
+                # Machine should gain IP address when comming up,
+                # so wait for dhcp lease and store IP into machines data_dir.
+                b3.use WaitTillUp
 
-              b3.use ForwardPorts
-              b3.use PrepareNFSSettings
-              b3.use ShareFolders
+                b3.use ForwardPorts
+                b3.use PrepareNFSSettings
+                b3.use ShareFolders
+             end
             end
           end
         end
@@ -101,7 +116,6 @@ module VagrantPlugins
       def self.action_halt
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
-          b.use ConnectLibvirt
           b.use ClearForwardedPorts
           b.use Call, IsCreated do |env, b2|
             if !env[:result]
@@ -144,7 +158,6 @@ module VagrantPlugins
       def self.action_package
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
-          b.use ConnectLibvirt
           b.use PackageDomain
         end
       end
@@ -157,9 +170,10 @@ module VagrantPlugins
           b.use Call, IsCreated do |env, b2|
             if !env[:result]
               # Try to remove stale volumes anyway
-              b2.use ConnectLibvirt
               b2.use SetNameOfDomain
-              b2.use RemoveStaleVolume
+              if env[:machine].box
+                b2.use RemoveStaleVolume
+              end
               if !env[:result]
                 b2.use MessageNotCreated
               end
@@ -167,11 +181,11 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use ClearForwardedPorts
             # b2.use PruneNFSExports
             b2.use DestroyDomain
             b2.use DestroyNetworks
+            b2.use ProvisionerCleanup
           end
         end
       end
@@ -186,7 +200,6 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use Call, IsRunning do |env2, b3|
               if !env2[:result]
                 b3.use MessageNotRunning
@@ -209,7 +222,6 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use Call, IsRunning do |env2, b3|
               if !env2[:result]
                 b3.use MessageNotRunning
@@ -234,7 +246,6 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use Call, IsRunning do |env2, b3|
               if !env2[:result]
                 b3.use MessageNotRunning
@@ -257,7 +268,6 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use Call, IsSuspended do |env2, b3|
               if !env2[:result]
                 b3.use MessageNotSuspended
@@ -269,31 +279,9 @@ module VagrantPlugins
         end
       end
 
-      # This action is called to read the state of the machine. The resulting
-      # state is expected to be put into the `:machine_state_id` key.
-      def self.action_read_state
-        Vagrant::Action::Builder.new.tap do |b|
-          b.use ConfigValidate
-          b.use ConnectLibvirt
-          b.use ReadState
-        end
-      end
-
-      # This action is called to read the SSH info of the machine. The
-      # resulting state is expected to be put into the `:machine_ssh_info`
-      # key.
-      def self.action_read_ssh_info
-        Vagrant::Action::Builder.new.tap do |b|
-          b.use ConfigValidate
-          b.use ConnectLibvirt
-          b.use ReadSSHInfo
-        end
-      end
-
       def self.action_read_mac_addresses
         Vagrant::Action::Builder.new.tap do |b|
           b.use ConfigValidate
-          b.use ConnectLibvirt
           b.use ReadMacAddresses
         end
       end
@@ -308,7 +296,6 @@ module VagrantPlugins
               next
             end
 
-            b2.use ConnectLibvirt
             b2.use Call, IsRunning do |env2, b3|
               if !env2[:result]
                 b3.use MessageNotRunning
@@ -323,7 +310,6 @@ module VagrantPlugins
       end
 
       action_root = Pathname.new(File.expand_path('../action', __FILE__))
-      autoload :ConnectLibvirt, action_root.join('connect_libvirt')
       autoload :PackageDomain, action_root.join('package_domain')
       autoload :CreateDomain, action_root.join('create_domain')
       autoload :CreateDomainVolume, action_root.join('create_domain_volume')
@@ -351,11 +337,10 @@ module VagrantPlugins
       autoload :PrepareNFSValidIds, action_root.join('prepare_nfs_valid_ids')
       autoload :PruneNFSExports, action_root.join('prune_nfs_exports')
 
-      autoload :ReadSSHInfo, action_root.join('read_ssh_info')
       autoload :ReadMacAddresses, action_root.join('read_mac_addresses')
-      autoload :ReadState, action_root.join('read_state')
       autoload :ResumeDomain, action_root.join('resume_domain')
       autoload :SetNameOfDomain, action_root.join('set_name_of_domain')
+      autoload :SetBootOrder, action_root.join('set_boot_order')
 
       # I don't think we need it anymore
       autoload :ShareFolders, action_root.join('share_folders')
@@ -370,6 +355,7 @@ module VagrantPlugins
       autoload :HandleBox, 'vagrant/action/builtin/handle_box'
       autoload :SyncedFolders, 'vagrant/action/builtin/synced_folders'
       autoload :SyncedFolderCleanup, 'vagrant/action/builtin/synced_folder_cleanup'
+      autoload :ProvisionerCleanup, 'vagrant/action/builtin/provisioner_cleanup'
     end
   end
 end
diff --git a/lib/vagrant-libvirt/action/connect_libvirt.rb b/lib/vagrant-libvirt/action/connect_libvirt.rb
deleted file mode 100644
index d34f6c5..0000000
--- a/lib/vagrant-libvirt/action/connect_libvirt.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require 'fog/libvirt'
-require 'log4r'
-
-module VagrantPlugins
-  module ProviderLibvirt
-    module Action
-      class ConnectLibvirt
-        def initialize(app, env)
-          @logger = Log4r::Logger.new('vagrant_libvirt::action::connect_libvirt')
-          @app = app
-        end
-
-        def call(env)
-          # If already connected to libvirt, just use it and don't connect
-          # again.
-          if ProviderLibvirt.libvirt_connection
-            env[:libvirt_compute] = ProviderLibvirt.libvirt_connection
-            return @app.call(env)
-          end
-
-          # Get config options for libvirt provider.
-          config = env[:machine].provider_config
-          uri = config.uri
-
-          conn_attr = {}
-          conn_attr[:provider] = 'libvirt'
-          conn_attr[:libvirt_uri] = uri
-          conn_attr[:libvirt_username] = config.username if config.username
-          conn_attr[:libvirt_password] = config.password if config.password
-
-          # Setup command for retrieving IP address for newly created machine
-          # with some MAC address. Get it from dnsmasq leases table
-          ip_command = %q[ awk "/$mac/ {print \$1}" /proc/net/arp ]
-          conn_attr[:libvirt_ip_command] = ip_command
-
-          @logger.info("Connecting to Libvirt (#{uri}) ...")
-          begin
-            env[:libvirt_compute] = Fog::Compute.new(conn_attr)
-          rescue Fog::Errors::Error => e
-            raise Errors::FogLibvirtConnectionError,
-              :error_message => e.message
-          end
-          ProviderLibvirt.libvirt_connection = env[:libvirt_compute]
-
-          @app.call(env)
-        end
-      end
-    end
-  end
-end
-
diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb
index 8909971..097a431 100644
--- a/lib/vagrant-libvirt/action/create_domain.rb
+++ b/lib/vagrant-libvirt/action/create_domain.rb
@@ -6,7 +6,7 @@ module VagrantPlugins
       class CreateDomain
         include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate
 
-        def initialize(app, env)
+        def initialize(app, _env)
           @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain')
           @app = app
         end
@@ -17,7 +17,7 @@ module VagrantPlugins
 
         def _disks_print(disks)
           disks.collect do |x|
-            x[:device] + '(' + x[:type] + ',' + x[:size] + ')'
+            "#{x[:device]}(#{x[:type]},#{x[:size]})"
           end.join(', ')
         end
 
@@ -33,11 +33,13 @@ module VagrantPlugins
           @name = env[:domain_name]
           @cpus = config.cpus.to_i
           @cpu_mode = config.cpu_mode
+          @loader = config.loader
           @machine_type = config.machine_type
           @machine_arch = config.machine_arch
           @disk_bus = config.disk_bus
           @nested = config.nested
           @memory_size = config.memory.to_i * 1024
+          @management_network_mac = config.management_network_mac
           @domain_volume_cache = config.volume_cache
           @kernel = config.kernel
           @cmd_line = config.cmd_line
@@ -49,12 +51,12 @@ module VagrantPlugins
           @graphics_passwd =  if config.graphics_passwd.to_s.empty?
                                 ''
                               else
-                                "passwd='#{config.graphics_passwd.to_s}'"
+                                "passwd='#{config.graphics_passwd}'"
                               end
           @video_type = config.video_type
           @video_vram = config.video_vram
           @keymap = config.keymap
-          
+
           # Boot order
           @boot_order = config.boot_order
 
@@ -63,19 +65,37 @@ module VagrantPlugins
           @disks = config.disks
           @cdroms = config.cdroms
 
+          # Input
+          @inputs = config.inputs
+
           config = env[:machine].provider_config
           @domain_type = config.driver
 
           @os_type = 'hvm'
 
-          # Get path to domain image.
-          domain_volume = ProviderLibvirt::Util::Collection.find_matching(
-            env[:libvirt_compute].volumes.all, "#{@name}.img")
-          raise Errors::DomainVolumeExists if domain_volume.nil?
-          @domain_volume_path = domain_volume.path
+          # Get path to domain image from the storage pool selected if we have a box.
+          if env[:machine].box
+            actual_volumes =
+              env[:machine].provider.driver.connection.volumes.all.select do |x|
+                x.pool_name == @storage_pool_name
+              end
+            domain_volume = ProviderLibvirt::Util::Collection.find_matching(
+              actual_volumes,"#{@name}.img")
+            raise Errors::DomainVolumeExists if domain_volume.nil?
+            @domain_volume_path = domain_volume.path
+          end
 
+          # If we have a box, take the path from the domain volume and set our storage_prefix.
+          # If not, we dump the storage pool xml to get its defined path.
           # the default storage prefix is typically: /var/lib/libvirt/images/
-          storage_prefix = File.dirname(@domain_volume_path) + '/'	# steal
+          if env[:machine].box
+            storage_prefix = File.dirname(@domain_volume_path) + '/'        # steal
+          else
+            storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name)
+            raise Errors::NoStoragePool if storage_pool.nil?
+            xml = Nokogiri::XML(storage_pool.xml_desc)
+            storage_prefix = xml.xpath("/pool/target/path").inner_text.to_s + '/'
+          end
 
           @disks.each do |disk|
             disk[:path] ||= _disk_name(@name, disk)
@@ -88,11 +108,13 @@ module VagrantPlugins
 
             disk[:absolute_path] = storage_prefix + disk[:path]
 
-            if env[:libvirt_compute].volumes.all.select {|x| x.name == disk[:name] }.empty?
+            if env[:machine].provider.driver.connection.volumes.select do |x|
+              x.name == disk[:name] && x.pool_name == @storage_pool_name
+            end.empty?
               # make the disk. equivalent to:
               # qemu-img create -f qcow2 <path> 5g
               begin
-                env[:libvirt_compute].volumes.create(
+                env[:machine].provider.driver.connection.volumes.create(
                   name: disk[:name],
                   format_type: disk[:type],
                   path: disk[:absolute_path],
@@ -114,9 +136,13 @@ module VagrantPlugins
           env[:ui].info(" -- Domain type:       #{@domain_type}")
           env[:ui].info(" -- Cpus:              #{@cpus}")
           env[:ui].info(" -- Memory:            #{@memory_size / 1024}M")
-          env[:ui].info(" -- Base box:          #{env[:machine].box.name}")
+          env[:ui].info(" -- Management MAC:    #{@management_network_mac}")
+          env[:ui].info(" -- Loader:            #{@loader}")
+          if env[:machine].box
+            env[:ui].info(" -- Base box:          #{env[:machine].box.name}")
+          end
           env[:ui].info(" -- Storage pool:      #{@storage_pool_name}")
-          env[:ui].info(" -- Image:             #{@domain_volume_path}")
+          env[:ui].info(" -- Image:             #{@domain_volume_path} (#{env[:box_virtual_size]}G)")
           env[:ui].info(" -- Volume Cache:      #{@domain_volume_cache}")
           env[:ui].info(" -- Kernel:            #{@kernel}")
           env[:ui].info(" -- Initrd:            #{@initrd}")
@@ -127,7 +153,7 @@ module VagrantPlugins
           env[:ui].info(" -- Video Type:        #{@video_type}")
           env[:ui].info(" -- Video VRAM:        #{@video_vram}")
           env[:ui].info(" -- Keymap:            #{@keymap}")
-          
+
           @boot_order.each do |device|
             env[:ui].info(" -- Boot device:        #{device}")
           end
@@ -138,8 +164,8 @@ module VagrantPlugins
 
           @disks.each do |disk|
             msg = " -- Disk(#{disk[:device]}):     #{disk[:absolute_path]}"
-            msg += " (shared. Remove only manualy)" if disk[:allow_existing]
-            msg += " Not created - using existed." if disk[:preexisting]
+            msg += ' (shared. Remove only manually)' if disk[:allow_existing]
+            msg += ' Not created - using existed.' if disk[:preexisting]
             env[:ui].info(msg)
           end
 
@@ -150,14 +176,16 @@ module VagrantPlugins
           @cdroms.each do |cdrom|
             env[:ui].info(" -- CDROM(#{cdrom[:dev]}):        #{cdrom[:path]}")
           end
-
+          @inputs.each do |input|
+            env[:ui].info(" -- INPUT : type=#{input[:type]}, bus=#{input[:bus]}")
+          end
           env[:ui].info(" -- Command line : #{@cmd_line}")
 
           # Create libvirt domain.
           # Is there a way to tell fog to create new domain with already
           # existing volume? Use domain creation from template..
           begin
-            server = env[:libvirt_compute].servers.create(
+            server = env[:machine].provider.driver.connection.servers.create(
               xml: to_xml('domain'))
           rescue Fog::Errors::Error => e
             raise Errors::FogCreateServerError, error_message:  e.message
diff --git a/lib/vagrant-libvirt/action/create_domain_volume.rb b/lib/vagrant-libvirt/action/create_domain_volume.rb
index 2d536b6..e5c1acf 100644
--- a/lib/vagrant-libvirt/action/create_domain_volume.rb
+++ b/lib/vagrant-libvirt/action/create_domain_volume.rb
@@ -26,21 +26,21 @@ module VagrantPlugins
 
           # Verify the volume doesn't exist already.
           domain_volume = ProviderLibvirt::Util::Collection.find_matching(
-            env[:libvirt_compute].volumes.all, @name)
+            env[:machine].provider.driver.connection.volumes.all, @name)
           raise Errors::DomainVolumeExists if domain_volume
 
           # Get path to backing image - box volume.
           box_volume = ProviderLibvirt::Util::Collection.find_matching(
-            env[:libvirt_compute].volumes.all, env[:box_volume_name])
+            env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name])
           @backing_file = box_volume.path
 
-          # Virtual size of image. Same as box image size.
-          @capacity = env[:machine].box.metadata['virtual_size'] #G
+          # Virtual size of image. Take value worked out by HandleBoxImage
+          @capacity = env[:box_virtual_size] #G
 
           # Create new volume from xml template. Fog currently doesn't support
           # volume snapshots directly.
           begin
-            domain_volume = env[:libvirt_compute].volumes.create(
+            domain_volume = env[:machine].provider.driver.connection.volumes.create(
               :xml       => to_xml('volume_snapshot'),
               :pool_name => config.storage_pool_name)
           rescue Fog::Errors::Error => e
diff --git a/lib/vagrant-libvirt/action/create_network_interfaces.rb b/lib/vagrant-libvirt/action/create_network_interfaces.rb
index 35886ad..866bf54 100644
--- a/lib/vagrant-libvirt/action/create_network_interfaces.rb
+++ b/lib/vagrant-libvirt/action/create_network_interfaces.rb
@@ -19,13 +19,14 @@ module VagrantPlugins
           @management_network_name = env[:machine].provider_config.management_network_name
 	        config = env[:machine].provider_config
 	        @nic_model_type = config.nic_model_type
+          @nic_adapter_count = config.nic_adapter_count
           @app = app
         end
 
         def call(env)
           # Get domain first.
           begin
-            domain = env[:libvirt_compute].client.lookup_domain_by_uuid(
+            domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
               env[:machine].id.to_s)
           rescue => e
             raise Errors::NoDomainError,
@@ -36,7 +37,6 @@ module VagrantPlugins
           adapters = []
 
           # Vagrant gives you adapter 0 by default
-
           # Assign interfaces to slots.
           configured_networks(env, @logger).each do |options|
 
@@ -60,7 +60,7 @@ module VagrantPlugins
             # We have slot for interface, fill it with interface configuration.
             adapters[free_slot] = options
             adapters[free_slot][:network_name] = interface_network(
-              env[:libvirt_compute].client, adapters[free_slot])
+              env[:machine].provider.driver.connection.client, adapters[free_slot])
           end
 
           # Create each interface as new domain device.
@@ -70,7 +70,6 @@ module VagrantPlugins
             @mac = iface_configuration.fetch(:mac, false)
             @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
             template_name = 'interface'
-
             # Configuration for public interfaces which use the macvtap driver
             if iface_configuration[:iface_type] == :public_network
               @device = iface_configuration.fetch(:dev, 'eth0')
@@ -80,8 +79,30 @@ module VagrantPlugins
               template_name = 'public_interface'
               @logger.info("Setting up public interface using device #{@device} in mode #{@mode}")
               @ovs = iface_configuration.fetch(:ovs, false)
+            # configuration for udp or tcp tunnel interfaces (p2p conn btwn guest OSes)
+            elsif iface_configuration.fetch(:tunnel_type, nil)
+              @type = iface_configuration.fetch(:tunnel_type)
+              @tunnel_port = iface_configuration.fetch(:tunnel_port, nil)
+              raise Errors::TunnelPortNotDefined if @tunnel_port.nil?
+              if @type == 'udp'
+                # default udp tunnel source to 127.0.0.1
+                @udp_tunnel_local_ip = iface_configuration.fetch(:tunnel_local_ip, '127.0.0.1')
+                @udp_tunnel_local_port = iface_configuration.fetch(:tunnel_local_port)
+              end
+              # default mcast tunnel to 239.255.1.1. Web search says this
+              # 239.255.x.x is a safe range to use for general use mcast
+              if @type == 'mcast'
+                default_ip = '239.255.1.1'
+              else
+                default_ip = '127.0.0.1'
+              end
+              @tunnel_ip = iface_configuration.fetch(:tunnel_address, default_ip)
+              @model_type = iface_configuration.fetch(:model_type, @nic_model_type)
+              template_name = 'tunnel_interface'
+              @logger.info("Setting up #{@type} tunnel interface using  #{@tunnel_ip} port #{@tunnel_port}")
             end
 
+
             message = "Creating network interface eth#{@iface_number}"
             message << " connected to network #{@network_name}."
             if @mac
@@ -96,58 +117,83 @@ module VagrantPlugins
               raise Errors::AttachDeviceError,
                 :error_message => e.message
             end
+
+            # Re-read the network configuration and grab the MAC address
+            unless @mac
+              xml = Nokogiri::XML(domain.xml_desc)
+              if iface_configuration[:iface_type] == :public_network
+                if @type == 'direct'
+                  @mac = xml.xpath("/domain/devices/interface[source[@dev='#{@device}']]/mac/@address")
+                else
+                  @mac = xml.xpath("/domain/devices/interface[source[@bridge='#{@device}']]/mac/@address")
+                end
+              else
+                @mac = xml.xpath("/domain/devices/interface[source[@network='#{@network_name}']]/mac/@address")
+              end
+              iface_configuration[:mac] = @mac.to_s
+            end
           end
 
           # Continue the middleware chain.
           @app.call(env)
 
-          # Configure interfaces that user requested. Machine should be up and
-          # running now.
-          networks_to_configure = []
-
-          adapters.each_with_index do |options, slot_number|
-            # Skip configuring the management network, which is on the first interface.
-            # It's used for provisioning and it has to be available during provisioning,
-            # ifdown command is not acceptable here.
-            next if slot_number == 0
-            next if options[:auto_config] === false
-            @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
-
-            network = {
-              :interface                       => slot_number,
-              :use_dhcp_assigned_default_route => options[:use_dhcp_assigned_default_route],
-              #:mac => ...,
-            }
-
-            if options[:ip]
+
+          if env[:machine].box
+            # Configure interfaces that user requested. Machine should be up and
+            # running now.
+            networks_to_configure = []
+
+            adapters.each_with_index do |options, slot_number|
+              # Skip configuring the management network, which is on the first interface.
+              # It's used for provisioning and it has to be available during provisioning,
+              # ifdown command is not acceptable here.
+              next if slot_number == 0
+              next if options[:auto_config] === false
+              @logger.debug "Configuring interface slot_number #{slot_number} options #{options}"
+
               network = {
-                :type    => :static,
-                :ip      => options[:ip],
-                :netmask => options[:netmask],
-              }.merge(network)
-            else
-              network[:type] = :dhcp
+                :interface                       => slot_number,
+                :use_dhcp_assigned_default_route => options[:use_dhcp_assigned_default_route],
+                :mac_address => options[:mac],
+              }
+
+              if options[:ip]
+                network = {
+                  :type    => :static,
+                  :ip      => options[:ip],
+                  :netmask => options[:netmask],
+                }.merge(network)
+              else
+                network[:type] = :dhcp
+              end
+
+              # do not run configure_networks for tcp tunnel interfaces
+              next if options.fetch(:tunnel_type, nil)
+
+              networks_to_configure << network
             end
 
-            networks_to_configure << network
-          end
+            env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
+            env[:machine].guest.capability(
+              :configure_networks, networks_to_configure)
 
-          env[:ui].info I18n.t('vagrant.actions.vm.network.configuring')
-          env[:machine].guest.capability(
-            :configure_networks, networks_to_configure)
+          end
         end
 
         private
 
-        def find_empty(array, start=0, stop=8)
+        def find_empty(array, start=0, stop=@nic_adapter_count)
           (start..stop).each do |i|
-            return i if !array[i]
+            return i unless array[i]
           end
           return nil
         end
 
         # Return network name according to interface options.
         def interface_network(libvirt_client, options)
+          # no need to get interface network for tcp tunnel config
+          return 'tunnel_interface' if options.fetch(:tunnel_type, nil)
+
           if options[:network_name]
             @logger.debug "Found network by name"
             return options[:network_name]
diff --git a/lib/vagrant-libvirt/action/create_networks.rb b/lib/vagrant-libvirt/action/create_networks.rb
index a0d4e54..b9dd295 100644
--- a/lib/vagrant-libvirt/action/create_networks.rb
+++ b/lib/vagrant-libvirt/action/create_networks.rb
@@ -23,7 +23,7 @@ module VagrantPlugins
 
           @available_networks = []
           @options = {}
-          @libvirt_client = env[:libvirt_compute].client
+          @libvirt_client = env[:machine].provider.driver.connection.client
         end
 
         def call(env)
@@ -35,7 +35,8 @@ module VagrantPlugins
             # available, create it if possible. Otherwise raise an error.
             configured_networks(env, @logger).each do |options|
               # Only need to create private networks
-              next if options[:iface_type] != :private_network
+              next if options[:iface_type] != :private_network ||
+                options.fetch(:tunnel_type, nil)
               @logger.debug "Searching for network with options #{options}"
 
               # should fix other methods so this doesn't have to be instance var
@@ -45,7 +46,7 @@ module VagrantPlugins
               # list is used throughout this class and should be easier to
               # process than libvirt API calls.
               @available_networks = libvirt_networks(
-                                      env[:libvirt_compute].client)
+                                      env[:machine].provider.driver.connection.client)
 
               # Prepare a hash describing network for this specific interface.
               @interface_network = {
@@ -62,15 +63,16 @@ module VagrantPlugins
 
               if @options[:ip]
                 handle_ip_option(env)
-              # in vagrant 1.2.3 and later it is not possible to take this branch
-              # because cannot have name without ip
-              # https://github.com/mitchellh/vagrant/commit/cf2f6da4dbcb4f57c9cdb3b94dcd0bba62c5f5fd
+              elsif @options[:type].to_s == 'dhcp'
+                handle_dhcp_private_network(env)
               elsif @options[:network_name]
-                handle_network_name_option
+                handle_network_name_option(env)
+              else
+                raise Errors::CreateNetworkError, error_message: @options
               end
 
-              autostart_network if !@interface_network[:autostart]
-              activate_network if !@interface_network[:active]
+              autostart_network if @interface_network[:autostart]
+              activate_network unless @interface_network[:active]
             end
           end
 
@@ -79,22 +81,21 @@ module VagrantPlugins
 
         private
 
+        def lookup_network_by_ip(ip)
+          @logger.debug "looking up network with ip == #{ip}"
+          @available_networks.find { |network| network[:network_address] == ip }
+        end
+
         # Return hash of network for specified name, or nil if not found.
         def lookup_network_by_name(network_name)
           @logger.debug "looking up network named #{network_name}"
-          @available_networks.each do |network|
-            return network if network[:name] == network_name
-          end
-          nil
+          @available_networks.find { |network| network[:name] == network_name }
         end
 
         # Return hash of network for specified bridge, or nil if not found.
         def lookup_bridge_by_name(bridge_name)
           @logger.debug "looking up bridge named #{bridge_name}"
-          @available_networks.each do |network|
-            return network if network[:bridge_name] == bridge_name
-          end
-          nil
+          @available_networks.find { |network| network[:bridge_name] == bridge_name }
         end
 
         # Throw an error if dhcp setting for an existing network does not
@@ -114,28 +115,30 @@ module VagrantPlugins
         # Handle only situations, when ip is specified. Variables @options and
         # @available_networks should be filled before calling this function.
         def handle_ip_option(env)
-          return if !@options[:ip]
+          return unless @options[:ip]
+          net_address = nil
+          unless @options[:forward_mode] == 'veryisolated'
+            net_address = network_address(@options[:ip], @options[:netmask])
+
+            # Set IP address of network (actually bridge). It will be used as
+            # gateway address for machines connected to this network.
+            @interface_network[:ip_address] = get_host_ip_addr(net_address)
+          end
 
-          net_address = network_address(@options[:ip], @options[:netmask])
           @interface_network[:network_address] = net_address
 
-          # Set IP address of network (actually bridge). It will be used as
-          # gateway address for machines connected to this network.
-          net = IPAddr.new(net_address)
-          # Default to first address (after network name)
-          @interface_network[:ip_address] = @options[:host_ip].nil? ? net.to_range.begin.succ : IPAddr.new(@options[:host_ip])
-
-          # Is there an available network matching to configured ip
-          # address?
-          @available_networks.each do |available_network|
-            if available_network[:network_address] == \
-            @interface_network[:network_address]
-              @interface_network = available_network
-              @logger.debug "found existing network by ip, values are"
-              @logger.debug @interface_network
-              break
-            end
+          # if network is veryisolated, search by name
+          if @options[:libvirt__forward_mode] == "veryisolated"
+            network = lookup_network_by_name(@options[:network_name])
+          elsif net_address
+            # otherwise, search by ip (if set)
+            network = lookup_network_by_ip(net_address)
+          else
+            # leaving this here to mimic prior behavior. If we get
+            # here, something's probably broken.
+            network = lookup_network_by_name(@options[:network_name])
           end
+          @interface_network = network if network
 
           if @interface_network[:created]
             verify_dhcp
@@ -167,7 +170,7 @@ module VagrantPlugins
           end
 
           # Do we need to create new network?
-          if !@interface_network[:created]
+          unless @interface_network[:created]
 
             # TODO: stop after some loops. Don't create infinite loops.
 
@@ -188,17 +191,7 @@ module VagrantPlugins
             end
 
             # Generate a unique name for network bridge.
-            count = 0
-            while @interface_network[:bridge_name].nil?
-              @logger.debug "generating name for bridge"
-              bridge_name = 'virbr'
-              bridge_name << count.to_s
-              count += 1
-
-              next if lookup_bridge_by_name(bridge_name)
-
-              @interface_network[:bridge_name] = bridge_name
-            end
+            @interface_network[:bridge_name] = generate_bridge_name
 
             # Create a private network.
             create_private_network(env)
@@ -208,16 +201,68 @@ module VagrantPlugins
         # Handle network_name option, if ip was not specified. Variables
         # @options and @available_networks should be filled before calling this
         # function.
-        def handle_network_name_option
-          return if @options[:ip] || !@options[:network_name]
+        def handle_network_name_option(env)
+          return if @options[:ip] || \
+                    !@options[:network_name] || \
+                    !@options[:libvirt__forward_mode] == "veryisolated"
+
+          network = lookup_network_by_name(@options[:network_name])
+          @interface_network = network if network
 
-          @interface_network = lookup_network_by_name(@options[:network_name])
-          if !@interface_network
+          # if this interface has a network address, something's wrong.
+          if @interface_network[:network_address]
             raise Errors::NetworkNotAvailableError,
                   network_name: @options[:network_name]
-          else
-            verify_dhcp
           end
+
+          # Do we need to create new network?
+          unless @interface_network[:created]
+            @interface_network[:name] = @options[:network_name]
+
+            # Generate a unique name for network bridge.
+            @interface_network[:bridge_name] = generate_bridge_name
+
+            # Create a private network.
+            create_private_network(env)
+          end
+        end
+
+        def handle_dhcp_private_network(env)
+          net_address = '172.28.128.0'
+          network = lookup_network_by_ip(net_address)
+          @interface_network = network if network
+
+          # Do we need to create new network?
+          unless @interface_network[:created]
+            @interface_network[:name] = 'vagrant-private-dhcp'
+            @interface_network[:network_address] = net_address
+
+            # Set IP address of network (actually bridge). It will be used as
+            # gateway address for machines connected to this network.
+            @interface_network[:ip_address] = get_host_ip_addr(net_address)
+
+            # Generate a unique name for network bridge.
+            @interface_network[:bridge_name] = generate_bridge_name
+
+            # Create a private network.
+            create_private_network(env)
+          end
+        end
+
+        # Return provided address or first address of network otherwise
+        def get_host_ip_addr(network)
+          @options[:host_ip] ? IPAddr.new(@options[:host_ip]) : IPAddr.new(network).succ
+        end
+
+        # Return the first available virbr interface name
+        def generate_bridge_name
+          @logger.debug "generating name for bridge"
+          count = 0
+          while lookup_bridge_by_name(bridge_name = "virbr#{count}")
+            count += 1
+          end
+          @logger.debug "found available bridge name #{bridge_name}"
+          bridge_name
         end
 
         def create_private_network(env)
@@ -235,7 +280,7 @@ module VagrantPlugins
             # Find out DHCP addresses pool range.
             network_address = "#{@interface_network[:network_address]}/"
             network_address << "#{@interface_network[:netmask]}"
-            net = IPAddr.new(network_address)
+            net = @interface_network[:network_address] ? IPAddr.new(network_address) : nil
 
             # First is address of network, second is gateway (by default).
             # So start the range two addresses after network address by default.
diff --git a/lib/vagrant-libvirt/action/destroy_domain.rb b/lib/vagrant-libvirt/action/destroy_domain.rb
index e4610be..52caa18 100644
--- a/lib/vagrant-libvirt/action/destroy_domain.rb
+++ b/lib/vagrant-libvirt/action/destroy_domain.rb
@@ -17,7 +17,7 @@ module VagrantPlugins
           # Fog libvirt currently doesn't support snapshots. Use
           # ruby-libvirt client directly. Note this is racy, see
           # http://www.libvirt.org/html/libvirt-libvirt.html#virDomainSnapshotListNames
-          libvirt_domain =  env[:libvirt_compute].client.lookup_domain_by_uuid(
+          libvirt_domain =  env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
                               env[:machine].id)
           libvirt_domain.list_snapshots.each do |name|
             @logger.info("Deleting snapshot '#{name}'")
@@ -28,7 +28,7 @@ module VagrantPlugins
             end
           end
 
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
 
           if env[:machine].provider_config.disks.empty?
             # if using default configuration of disks
@@ -37,10 +37,10 @@ module VagrantPlugins
             domain.destroy(destroy_volumes: false)
 
             env[:machine].provider_config.disks.each do |disk|
-              # shared disks remove only manualy or ???
+              # shared disks remove only manually or ???
               next if disk[:allow_existing]
               diskname = libvirt_domain.name + '-' + disk[:device] + '.' + disk[:type].to_s
-              # diskname is uniq
+              # diskname is unique
               libvirt_disk = domain.volumes.select do |x|
                 x.name == diskname
               end.first
diff --git a/lib/vagrant-libvirt/action/destroy_networks.rb b/lib/vagrant-libvirt/action/destroy_networks.rb
index 6dfcaca..2f9852e 100644
--- a/lib/vagrant-libvirt/action/destroy_networks.rb
+++ b/lib/vagrant-libvirt/action/destroy_networks.rb
@@ -36,7 +36,7 @@ module VagrantPlugins
             # lookup_network_by_uuid throws same exception
             # if there is an error or if the network just doesn't exist
             begin
-              libvirt_network = env[:libvirt_compute].client.lookup_network_by_uuid(
+              libvirt_network = env[:machine].provider.driver.connection.client.lookup_network_by_uuid(
                 network_uuid)
             rescue Libvirt::RetrieveError => e
               # this network is already destroyed, so move on
@@ -66,7 +66,7 @@ module VagrantPlugins
               libvirt_network.undefine
               @logger.info "Undefined it"
             rescue => e
-              raise Error::DestroyNetworkError,
+              raise Errors::DestroyNetworkError,
                 network_name: libvirt_network.name,
                 error_message: e.message
             end
diff --git a/lib/vagrant-libvirt/action/halt_domain.rb b/lib/vagrant-libvirt/action/halt_domain.rb
index bf84c95..392f5dd 100644
--- a/lib/vagrant-libvirt/action/halt_domain.rb
+++ b/lib/vagrant-libvirt/action/halt_domain.rb
@@ -13,7 +13,7 @@ module VagrantPlugins
         def call(env)
           env[:ui].info(I18n.t("vagrant_libvirt.halt_domain"))
 
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
 
           @logger.info("Trying gracefull shutdown.")
diff --git a/lib/vagrant-libvirt/action/handle_box_image.rb b/lib/vagrant-libvirt/action/handle_box_image.rb
index 45dacf0..2db7718 100644
--- a/lib/vagrant-libvirt/action/handle_box_image.rb
+++ b/lib/vagrant-libvirt/action/handle_box_image.rb
@@ -37,10 +37,30 @@ module VagrantPlugins
           env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub("/", "-VAGRANTSLASH-")
           env[:box_volume_name] << "_vagrant_box_image_#{env[:machine].box.version.to_s rescue ''}.img"
 
+          # Override box_virtual_size
+          if config.machine_virtual_size
+            if config.machine_virtual_size < box_virtual_size
+              # Warn that a virtual size less than the box metadata size
+              # is not supported and will be ignored
+              env[:ui].warn I18n.t(
+                'vagrant_libvirt.warnings.ignoring_virtual_size_too_small',
+                requested: config.machine_virtual_size, minimum: box_virtual_size
+              )
+            else
+              env[:ui].info I18n.t('vagrant_libvirt.manual_resize_required')
+              box_virtual_size = config.machine_virtual_size
+            end
+          end
+          # save for use by later actions
+          env[:box_virtual_size] = box_virtual_size
+
+          # while inside the synchronize block take care not to call the next
+          # action in the chain, as must exit this block first to prevent
+          # locking all subsequent actions as well.
           @@lock.synchronize do
             # Don't continue if image already exists in storage pool.
-            return @app.call(env) if ProviderLibvirt::Util::Collection.find_matching(
-              env[:libvirt_compute].volumes.all, env[:box_volume_name])
+            break if ProviderLibvirt::Util::Collection.find_matching(
+              env[:machine].provider.driver.connection.volumes.all, env[:box_volume_name])
 
             # Box is not available as a storage pool volume. Create and upload
             # it as a copy of local box image.
@@ -53,7 +73,7 @@ module VagrantPlugins
             message << " in storage pool #{config.storage_pool_name}."
             @logger.info(message)
             begin
-              fog_volume = env[:libvirt_compute].volumes.create(
+              fog_volume = env[:machine].provider.driver.connection.volumes.create(
                 name:         env[:box_volume_name],
                 allocation:   "#{box_image_size/1024/1024}M",
                 capacity:     "#{box_virtual_size}G",
@@ -97,10 +117,10 @@ module VagrantPlugins
           image_size = File.size(image_file) # B
 
           begin
-            pool = env[:libvirt_compute].client.lookup_storage_pool_by_name(
+            pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(
               pool_name)
             volume = pool.lookup_volume_by_name(volume_name)
-            stream = env[:libvirt_compute].client.stream
+            stream = env[:machine].provider.driver.connection.client.stream
             volume.upload(stream, offset=0, length=image_size)
 
             # Exception ProviderLibvirt::RetrieveError can be raised if buffer is
diff --git a/lib/vagrant-libvirt/action/handle_storage_pool.rb b/lib/vagrant-libvirt/action/handle_storage_pool.rb
index e405638..2f2bf8e 100644
--- a/lib/vagrant-libvirt/action/handle_storage_pool.rb
+++ b/lib/vagrant-libvirt/action/handle_storage_pool.rb
@@ -14,14 +14,16 @@ module VagrantPlugins
         end
 
         def call(env)
-          @@lock.synchronize do
-            # Get config options.
-            config = env[:machine].provider_config
+          # Get config options.
+          config = env[:machine].provider_config
 
+          # while inside the synchronize block take care not to call the next
+          # action in the chain, as must exit this block first to prevent
+          # locking all subsequent actions as well.
+          @@lock.synchronize do
             # Check for storage pool, where box image should be created
-            fog_pool = ProviderLibvirt::Util::Collection.find_matching(
-              env[:libvirt_compute].pools.all, config.storage_pool_name)
-            return @app.call(env) if fog_pool
+            break if ProviderLibvirt::Util::Collection.find_matching(
+              env[:machine].provider.driver.connection.pools.all, config.storage_pool_name)
 
             @logger.info("No storage pool '#{config.storage_pool_name}' is available.")
 
@@ -34,7 +36,7 @@ module VagrantPlugins
             # Fog libvirt currently doesn't support creating pools. Use
             # ruby-libvirt client directly.
             begin
-              libvirt_pool = env[:libvirt_compute].client.define_storage_pool_xml(
+              libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml(
                 to_xml('default_storage_pool'))
               libvirt_pool.build
               libvirt_pool.create
diff --git a/lib/vagrant-libvirt/action/is_running.rb b/lib/vagrant-libvirt/action/is_running.rb
index f2d47e5..6512c12 100644
--- a/lib/vagrant-libvirt/action/is_running.rb
+++ b/lib/vagrant-libvirt/action/is_running.rb
@@ -9,7 +9,7 @@ module VagrantPlugins
         end
 
         def call(env)
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
           env[:result] = domain.state.to_s == 'running'
 
diff --git a/lib/vagrant-libvirt/action/is_suspended.rb b/lib/vagrant-libvirt/action/is_suspended.rb
index 6bb3257..b5bf3d0 100644
--- a/lib/vagrant-libvirt/action/is_suspended.rb
+++ b/lib/vagrant-libvirt/action/is_suspended.rb
@@ -9,7 +9,7 @@ module VagrantPlugins
         end
 
         def call(env)
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
           env[:result] = domain.state.to_s == 'paused'
 
diff --git a/lib/vagrant-libvirt/action/package_domain.rb b/lib/vagrant-libvirt/action/package_domain.rb
index c9ce42a..ab3aec5 100644
--- a/lib/vagrant-libvirt/action/package_domain.rb
+++ b/lib/vagrant-libvirt/action/package_domain.rb
@@ -14,9 +14,9 @@ module VagrantPlugins
 
         def call(env)
           env[:ui].info(I18n.t('vagrant_libvirt.package_domain'))
-          libvirt_domain =  env[:libvirt_compute].client.lookup_domain_by_uuid(
+          libvirt_domain =  env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
                               env[:machine].id)
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           root_disk = domain.volumes.select do |x|
             x.name == libvirt_domain.name + '.img'
           end.first
@@ -37,7 +37,7 @@ module VagrantPlugins
           `qemu-img rebase -p -b "" #{@tmp_img}`
           # remove hw association with interface
           # working for centos with lvs default disks
-          `virt-sysprep --no-logfile  -a #{@tmp_img} `
+          `virt-sysprep --no-logfile --operations defaults,-ssh-userdir -a #{@tmp_img} `
           Dir.chdir(@tmp_dir)
           img_size = `qemu-img info #{@tmp_img} | grep 'virtual size' | awk '{print $3;}' | tr -d 'G'`.chomp
           File.write(@tmp_dir + '/metadata.json', metadata_content(img_size))
diff --git a/lib/vagrant-libvirt/action/prepare_nfs_settings.rb b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb
index b74268a..cdd9292 100644
--- a/lib/vagrant-libvirt/action/prepare_nfs_settings.rb
+++ b/lib/vagrant-libvirt/action/prepare_nfs_settings.rb
@@ -39,13 +39,16 @@ module VagrantPlugins
         #
         # @param [Machine] machine
         # @return [String]
-        def read_host_ip(ip)
-          UDPSocket.open do |s|
+	def read_host_ip(ip)
+      UDPSocket.open do |s|
+        if(ip.kind_of?(Array))
+            s.connect(ip.last, 1)
+        else
             s.connect(ip, 1)
-            s.addr.last
-          end
         end
-
+        s.addr.last
+      end
+    end
         # Returns the IP address of the guest
         #
         # @param [Machine] machine
diff --git a/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb b/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb
index 0eaf69d..2fe086a 100644
--- a/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb
+++ b/lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb
@@ -8,7 +8,7 @@ module VagrantPlugins
         end
 
         def call(env)
-          env[:nfs_valid_ids] = env[:libvirt_compute].servers.all.map(&:id)
+          env[:nfs_valid_ids] = env[:machine].provider.driver.connection.servers.all.map(&:id)
           @app.call(env)
         end
       end
diff --git a/lib/vagrant-libvirt/action/prune_nfs_exports.rb b/lib/vagrant-libvirt/action/prune_nfs_exports.rb
index 3b8eef8..3d2bc8a 100644
--- a/lib/vagrant-libvirt/action/prune_nfs_exports.rb
+++ b/lib/vagrant-libvirt/action/prune_nfs_exports.rb
@@ -12,7 +12,7 @@ module VagrantPlugins
           if env[:host]
             uuid = env[:machine].id
             # get all uuids
-            uuids = env[:libvirt_compute].servers.all.map(&:id)
+            uuids = env[:machine].provider.driver.connection.servers.all.map(&:id)
             # not exiisted in array will removed from nfs
             uuids.delete(uuid)
             env[:host].capability(
diff --git a/lib/vagrant-libvirt/action/read_mac_addresses.rb b/lib/vagrant-libvirt/action/read_mac_addresses.rb
index 42db4c0..b4f1063 100644
--- a/lib/vagrant-libvirt/action/read_mac_addresses.rb
+++ b/lib/vagrant-libvirt/action/read_mac_addresses.rb
@@ -10,7 +10,7 @@ module VagrantPlugins
         end
 
         def call(env)
-          env[:machine_mac_addresses] = read_mac_addresses(env[:libvirt_compute], env[:machine])
+          env[:machine_mac_addresses] = read_mac_addresses(env[:machine].provider.driver.connection, env[:machine])
         end
 
         def read_mac_addresses(libvirt, machine)
diff --git a/lib/vagrant-libvirt/action/read_ssh_info.rb b/lib/vagrant-libvirt/action/read_ssh_info.rb
deleted file mode 100644
index 3d7ea9d..0000000
--- a/lib/vagrant-libvirt/action/read_ssh_info.rb
+++ /dev/null
@@ -1,68 +0,0 @@
-require "log4r"
-
-module VagrantPlugins
-  module ProviderLibvirt
-    module Action
-      # This action reads the SSH info for the machine and puts it into the
-      # `:machine_ssh_info` key in the environment.
-      class ReadSSHInfo
-        def initialize(app, env)
-          @app    = app
-          @logger = Log4r::Logger.new("vagrant_libvirt::action::read_ssh_info")
-        end
-
-        def call(env)
-          env[:machine_ssh_info] = read_ssh_info(env[:libvirt_compute],
-                                                 env[:machine])
-
-          @app.call(env)
-        end
-
-        def read_ssh_info(libvirt, machine)
-          return nil if machine.id.nil?
-          return nil if machine.state.id != :running
-
-          # Find the machine
-          domain = libvirt.servers.get(machine.id)
-          if domain.nil?
-            # The machine can't be found
-            @logger.info("Machine couldn't be found, assuming it got destroyed.")
-            machine.id = nil
-            return nil
-          end
-
-          # Get IP address from dnsmasq lease file.
-          ip_address = nil
-          begin
-            domain.wait_for(2) do
-              addresses.each_pair do |type, ip|
-                # Multiple leases are separated with a newline, return only
-                # the most recent address
-                ip_address = ip[0].split("\n").first if ip[0] != nil
-              end
-              ip_address != nil
-            end
-          rescue Fog::Errors::TimeoutError
-            @logger.info("Timeout at waiting for an ip address for machine %s" % machine.name)
-          end
-
-          if not ip_address
-            @logger.info("No lease found for machine %s" % machine.name)
-            return nil
-          end
-
-          ssh_info = {
-            :host          => ip_address,
-            :port          => machine.config.ssh.guest_port,
-            :forward_agent => machine.config.ssh.forward_agent,
-            :forward_x11   => machine.config.ssh.forward_x11,
-          }
-
-          ssh_info[:proxy_command] = "ssh '#{machine.provider_config.host}' -l '#{machine.provider_config.username}' -i '#{machine.provider_config.id_ssh_key_file}' nc %h %p" if machine.provider_config.connect_via_ssh
-
-          ssh_info
-        end
-      end
-    end
-  end
-end
diff --git a/lib/vagrant-libvirt/action/read_state.rb b/lib/vagrant-libvirt/action/read_state.rb
deleted file mode 100644
index 1848de4..0000000
--- a/lib/vagrant-libvirt/action/read_state.rb
+++ /dev/null
@@ -1,60 +0,0 @@
-require 'log4r'
-
-module VagrantPlugins
-  module ProviderLibvirt
-    module Action
-      # This action reads the state of the machine and puts it in the
-      # `:machine_state_id` key in the environment.
-      class ReadState
-        def initialize(app, env)
-          @app    = app
-          @logger = Log4r::Logger.new('vagrant_libvirt::action::read_state')
-        end
-
-        def call(env)
-          env[:machine_state_id] = read_state(env[:libvirt_compute], env[:machine])
-          @app.call(env)
-        end
-
-        def read_state(libvirt, machine)
-          return :not_created if machine.id.nil?
-
-          begin
-            server = libvirt.servers.get(machine.id)
-          rescue Libvirt::RetrieveError => e
-            server = nil
-            @logger.debug('Machine not found #{e}.')
-          end
-          # Find the machine
-          begin
-            # Wait for libvirt to shutdown the domain
-            while libvirt.servers.get(machine.id).state.to_sym == :'shutting-down' do
-              @logger.info('Waiting on the machine to shut down...')
-              sleep 1
-            end
-
-            server = libvirt.servers.get(machine.id)
-
-            if server.nil? || server.state.to_sym == :terminated
-              # The machine can't be found
-              @logger.info('Machine terminated, assuming it got destroyed.')
-              machine.id = nil
-              return :not_created
-            end
-          rescue Libvirt::RetrieveError => e
-            if e.libvirt_code == ProviderLibvirt::Util::ErrorCodes::VIR_ERR_NO_DOMAIN
-              @logger.info("Machine #{machine.id} not found.")
-              machine.id = nil
-              return :not_created
-            else
-              raise e
-            end
-          end
-
-          # Return the state
-          return server.state.to_sym
-        end
-      end
-    end
-  end
-end
diff --git a/lib/vagrant-libvirt/action/remove_libvirt_image.rb b/lib/vagrant-libvirt/action/remove_libvirt_image.rb
index 554f0a7..4fd6649 100644
--- a/lib/vagrant-libvirt/action/remove_libvirt_image.rb
+++ b/lib/vagrant-libvirt/action/remove_libvirt_image.rb
@@ -11,7 +11,7 @@ module VagrantPlugins
 
         def call(env)
           env[:ui].info("Vagrant-libvirt plugin removed box only from you LOCAL ~/.vagrant/boxes directory")
-          env[:ui].info("From libvirt storage pool you have to delete image manualy(virsh, virt-manager or by any other tool)")
+          env[:ui].info("From libvirt storage pool you have to delete image manually(virsh, virt-manager or by any other tool)")
           @app.call(env)
         end
       end
diff --git a/lib/vagrant-libvirt/action/remove_stale_volume.rb b/lib/vagrant-libvirt/action/remove_stale_volume.rb
index 5b3c876..88dfcbe 100644
--- a/lib/vagrant-libvirt/action/remove_stale_volume.rb
+++ b/lib/vagrant-libvirt/action/remove_stale_volume.rb
@@ -22,7 +22,7 @@ module VagrantPlugins
           config = env[:machine].provider_config
           # Check for storage pool, where box image should be created
           fog_pool = ProviderLibvirt::Util::Collection.find_matching(
-            env[:libvirt_compute].pools.all, config.storage_pool_name)
+            env[:machine].provider.driver.connection.pools.all, config.storage_pool_name)
           @logger.debug("**** Pool #{fog_pool.name}")
 
           # This is name of newly created image for vm.
@@ -31,7 +31,7 @@ module VagrantPlugins
 
           # remove root storage
           box_volume = ProviderLibvirt::Util::Collection.find_matching(
-            env[:libvirt_compute].volumes.all, name)
+            env[:machine].provider.driver.connection.volumes.all, name)
           if box_volume && box_volume.pool_name == fog_pool.name
             @logger.info("Deleting volume #{box_volume.key}")
             box_volume.destroy
diff --git a/lib/vagrant-libvirt/action/resume_domain.rb b/lib/vagrant-libvirt/action/resume_domain.rb
index 38a9810..1f0dc84 100644
--- a/lib/vagrant-libvirt/action/resume_domain.rb
+++ b/lib/vagrant-libvirt/action/resume_domain.rb
@@ -13,7 +13,7 @@ module VagrantPlugins
         def call(env)
           env[:ui].info(I18n.t("vagrant_libvirt.resuming_domain"))
 
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
 
           domain.resume
diff --git a/lib/vagrant-libvirt/action/set_boot_order.rb b/lib/vagrant-libvirt/action/set_boot_order.rb
new file mode 100644
index 0000000..ec118a8
--- /dev/null
+++ b/lib/vagrant-libvirt/action/set_boot_order.rb
@@ -0,0 +1,66 @@
+require "log4r"
+require 'nokogiri'
+
+module VagrantPlugins
+  module ProviderLibvirt
+    module Action
+      class SetBootOrder
+        def initialize(app, env)
+          @app    = app
+          @logger = Log4r::Logger.new("vagrant_libvirt::action::set_boot_order")
+          config = env[:machine].provider_config
+          @boot_order = config.boot_order
+        end
+
+        def call(env)
+         # Get domain first
+          begin
+            domain = env[:machine].provider.driver.connection.client.lookup_domain_by_uuid(
+              env[:machine].id.to_s)
+          rescue => e
+            raise Errors::NoDomainError,
+              :error_message => e.message
+          end
+
+          # Only execute specific boot ordering if this is defined in the Vagrant file
+          if @boot_order.count >= 1
+          
+            # If a domain is initially defined with no box or disk or with an explicit boot order, libvirt adds <boot dev="foo">
+            # This conflicts with an explicit boot_order configuration, so we need to remove it from the domain xml and feed it back.
+            # Also see https://bugzilla.redhat.com/show_bug.cgi?id=1248514 as to why we have to do this after all devices have been defined.
+            xml = Nokogiri::XML(domain.xml_desc)
+            xml.search("/domain/os/boot").each do |node|
+              node.remove
+            end
+
+            # Parse the XML and find each defined drive and network interfacee
+            hd = xml.search("/domain/devices/disk[@device='disk']")
+            cdrom = xml.search("/domain/devices/disk[@device='cdrom']")
+            network = xml.search("/domain/devices/interface[@type='network']")
+
+            # Generate an array per device group and a flattened array from all of those
+            devices = {"hd" => hd, "cdrom" => cdrom, "network" => network}
+            final_boot_order = @boot_order.flat_map {|category| devices[category] }
+
+            # Loop over the entire defined boot order array and create boot order entries in the domain XML
+            final_boot_order.each_with_index do |node, index|
+              boot = "<boot order='#{index+1}'/>"
+              node.add_child(boot)
+              if node.name == 'disk'
+                @logger.debug "Setting #{node['device']} to boot index #{index+1}"
+              elsif node.name == 'interface'
+                @logger.debug "Setting #{node.name} to boot index #{index+1}"
+              end
+            end
+
+            # Finally redefine the domain XML through libvirt to apply the boot ordering
+            env[:machine].provider.driver.connection.client.define_domain_xml(xml.to_s)
+          end
+
+          @app.call(env)
+
+        end
+      end
+    end
+  end
+end
diff --git a/lib/vagrant-libvirt/action/set_name_of_domain.rb b/lib/vagrant-libvirt/action/set_name_of_domain.rb
index 99bc330..e22f710 100644
--- a/lib/vagrant-libvirt/action/set_name_of_domain.rb
+++ b/lib/vagrant-libvirt/action/set_name_of_domain.rb
@@ -14,11 +14,12 @@ module VagrantPlugins
           env[:domain_name] = build_domain_name(env)
 
           begin
-            @logger.info("Looking for domain #{env[:domain_name]} through list #{env[:libvirt_compute].servers.all}")
+            @logger.info("Looking for domain #{env[:domain_name]} through list " +
+                         "#{env[:machine].provider.driver.connection.servers.all}")
             # Check if the domain name is not already taken
 
             domain = ProviderLibvirt::Util::Collection.find_matching(
-              env[:libvirt_compute].servers.all, env[:domain_name])
+              env[:machine].provider.driver.connection.servers.all, env[:domain_name])
           rescue Fog::Errors::Error => e
             @logger.info("#{e}")
             domain = nil
diff --git a/lib/vagrant-libvirt/action/start_domain.rb b/lib/vagrant-libvirt/action/start_domain.rb
index 0d23d70..f03b13b 100644
--- a/lib/vagrant-libvirt/action/start_domain.rb
+++ b/lib/vagrant-libvirt/action/start_domain.rb
@@ -14,7 +14,7 @@ module VagrantPlugins
         def call(env)
           env[:ui].info(I18n.t("vagrant_libvirt.starting_domain"))
 
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
 
           begin
diff --git a/lib/vagrant-libvirt/action/suspend_domain.rb b/lib/vagrant-libvirt/action/suspend_domain.rb
index a350cbc..60027c4 100644
--- a/lib/vagrant-libvirt/action/suspend_domain.rb
+++ b/lib/vagrant-libvirt/action/suspend_domain.rb
@@ -14,7 +14,7 @@ module VagrantPlugins
         def call(env)
           env[:ui].info(I18n.t("vagrant_libvirt.suspending_domain"))
 
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise Errors::NoDomainError if domain == nil
 
           domain.suspend
diff --git a/lib/vagrant-libvirt/action/wait_till_up.rb b/lib/vagrant-libvirt/action/wait_till_up.rb
index 0081b23..431a35f 100644
--- a/lib/vagrant-libvirt/action/wait_till_up.rb
+++ b/lib/vagrant-libvirt/action/wait_till_up.rb
@@ -21,7 +21,7 @@ module VagrantPlugins
           env[:metrics] ||= {}
 
           # Get domain object
-          domain = env[:libvirt_compute].servers.get(env[:machine].id.to_s)
+          domain = env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s)
           raise NoDomainError if domain == nil
 
           # Wait for domain to obtain an ip address. Ip address is searched
diff --git a/lib/vagrant-libvirt/cap/mount_p9.rb b/lib/vagrant-libvirt/cap/mount_p9.rb
index 274edb1..b788809 100644
--- a/lib/vagrant-libvirt/cap/mount_p9.rb
+++ b/lib/vagrant-libvirt/cap/mount_p9.rb
@@ -1,3 +1,4 @@
+require "digest/md5"
 require "vagrant/util/retryable"
 
 module VagrantPlugins
@@ -16,7 +17,7 @@ module VagrantPlugins
             machine.communicate.sudo("mkdir -p #{expanded_guest_path}")
 
             # Mount
-            mount_tag = name.dup
+            mount_tag = Digest::MD5.new.update(opts[:hostpath]).to_s[0,31]
 
             mount_opts="-o trans=virtio"
             mount_opts += ",access=#{opts[:owner]}" if opts[:owner]
diff --git a/lib/vagrant-libvirt/cap/synced_folder.rb b/lib/vagrant-libvirt/cap/synced_folder.rb
index 95e4ef7..6821a44 100644
--- a/lib/vagrant-libvirt/cap/synced_folder.rb
+++ b/lib/vagrant-libvirt/cap/synced_folder.rb
@@ -1,6 +1,7 @@
 require 'log4r'
 require 'ostruct'
 require 'nokogiri'
+require "digest/md5"
 
 require 'vagrant/util/subprocess'
 require 'vagrant/errors'
@@ -24,13 +25,13 @@ module VagrantPlugins
 
         # <filesystem/> support in device attach/detach introduced in 1.2.2
         # version number format is major * 1,000,000 + minor * 1,000 + release
-        libvirt_version = ProviderLibvirt.libvirt_connection.client.libversion
+        libvirt_version = machine.provider.driver.connection.client.libversion
         libvirt_version >= 1_002_002
       end
 
       def prepare(machine, folders, _opts)
-        raise Vagrant::Errors::Error('No libvirt connection') if ProviderLibvirt.libvirt_connection.nil?
-        @conn = ProviderLibvirt.libvirt_connection.client
+        raise Vagrant::Errors::Error('No libvirt connection') if machine.provider.driver.connection.nil?
+        @conn = machine.provider.driver.connection.client
 
         begin
           # loop through folders
@@ -38,7 +39,12 @@ module VagrantPlugins
             folder_opts.merge!({  target: id,
                                   accessmode: 'passthrough',
                                   readonly: nil }) { |_k, ov, _nv| ov }
+
+            mount_tag = Digest::MD5.new.update(folder_opts[:hostpath]).to_s[0,31]
+            folder_opts[:mount_tag] = mount_tag
+            
             machine.ui.info "================\nMachine id: #{machine.id}\nShould be mounting folders\n #{id}, opts: #{folder_opts}"
+            
             xml =  to_xml('filesystem', folder_opts)
             # puts "<<<<< XML:\n #{xml}\n >>>>>"
             @conn.lookup_domain_by_uuid(machine.id).attach_device(xml, 0)
@@ -67,10 +73,10 @@ module VagrantPlugins
       end
 
       def cleanup(machine, _opts)
-        if ProviderLibvirt.libvirt_connection.nil?
+        if machine.provider.driver.connection.nil?
           raise Vagrant::Errors::Error('No libvirt connection')
         end
-        @conn = ProviderLibvirt.libvirt_connection.client
+        @conn = machine.provider.driver.connection.client
         begin
           if machine.id && machine.id != ''
             dom = @conn.lookup_domain_by_uuid(machine.id)
diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb
index bc446d6..5af49e7 100644
--- a/lib/vagrant-libvirt/config.rb
+++ b/lib/vagrant-libvirt/config.rb
@@ -47,6 +47,7 @@ module VagrantPlugins
       attr_accessor :management_network_name
       attr_accessor :management_network_address
       attr_accessor :management_network_mode
+      attr_accessor :management_network_mac
 
       # Default host prefix (alternative to use project folder name)
       attr_accessor :default_prefix
@@ -55,9 +56,11 @@ module VagrantPlugins
       attr_accessor :memory
       attr_accessor :cpus
       attr_accessor :cpu_mode
+      attr_accessor :loader
       attr_accessor :boot_order
       attr_accessor :machine_type
       attr_accessor :machine_arch
+      attr_accessor :machine_virtual_size
       attr_accessor :disk_bus
       attr_accessor :nic_model_type
       attr_accessor :nested
@@ -74,9 +77,17 @@ module VagrantPlugins
       attr_accessor :video_vram
       attr_accessor :keymap
 
+      # Sets the max number of NICs that can be created
+      # Default set to 8. Don't change the default unless you know
+      # what are doing
+      attr_accessor :nic_adapter_count
+
       # Storage
       attr_accessor :disks
-  	  attr_accessor :cdroms
+      attr_accessor :cdroms
+
+      # Inputs
+      attr_accessor :inputs
 
       def initialize
         @uri               = UNSET_VALUE
@@ -91,13 +102,16 @@ module VagrantPlugins
         @management_network_name    = UNSET_VALUE
         @management_network_address = UNSET_VALUE
         @management_network_mode = UNSET_VALUE
+        @management_network_mac  = UNSET_VALUE
 
         # Domain specific settings.
         @memory            = UNSET_VALUE
         @cpus              = UNSET_VALUE
         @cpu_mode          = UNSET_VALUE
+        @loader            = UNSET_VALUE
         @machine_type      = UNSET_VALUE
         @machine_arch      = UNSET_VALUE
+        @machine_virtual_size = UNSET_VALUE
         @disk_bus          = UNSET_VALUE
         @nic_model_type    = UNSET_VALUE
         @nested            = UNSET_VALUE
@@ -114,13 +128,18 @@ module VagrantPlugins
         @video_vram        = UNSET_VALUE
         @keymap            = UNSET_VALUE
 
+        @nic_adapter_count = UNSET_VALUE
+
         # Boot order
         @boot_order = []
         # Storage
         @disks             = []
-        @cdroms			       = []
+        @cdroms			   = []
+
+        # Inputs
+        @inputs            = UNSET_VALUE
       end
-      
+
       def boot(device)
         @boot_order << device	# append
       end
@@ -153,7 +172,22 @@ module VagrantPlugins
         end
 
         # is it better to raise our own error, or let libvirt cause the exception?
-        raise "Only four cdroms may be attached at a time"
+        raise 'Only four cdroms may be attached at a time'
+      end
+
+      def input(options={})
+        if options[:type].nil? || options[:bus].nil?
+          raise 'Input type AND bus must be specified'
+        end
+
+        if @inputs == UNSET_VALUE
+          @inputs = []
+        end
+
+        @inputs.push({
+          type: options[:type],
+          bus:  options[:bus]
+        })
       end
 
       # NOTE: this will run twice for each time it's needed- keep it idempotent
@@ -277,6 +311,7 @@ module VagrantPlugins
         @management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE
         @management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE
         @management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE
+        @management_network_mac = nil if @management_network_mac == UNSET_VALUE
 
         # generate a URI if none is supplied
         @uri = _generate_uri() if @uri == UNSET_VALUE
@@ -285,8 +320,10 @@ module VagrantPlugins
         @memory = 512 if @memory == UNSET_VALUE
         @cpus = 1 if @cpus == UNSET_VALUE
         @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE
+        @loader = nil if @loader == UNSET_VALUE
         @machine_type = nil if @machine_type == UNSET_VALUE
         @machine_arch = nil if @machine_arch == UNSET_VALUE
+        @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE
         @disk_bus = 'virtio' if @disk_bus == UNSET_VALUE
         @nic_model_type = 'virtio' if @nic_model_type == UNSET_VALUE
         @nested = false if @nested == UNSET_VALUE
@@ -306,13 +343,15 @@ module VagrantPlugins
         @video_type = 'cirrus' if @video_type == UNSET_VALUE
         @video_vram = 9216 if @video_vram == UNSET_VALUE
         @keymap = 'en-us' if @keymap == UNSET_VALUE
-        
+        @nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE
+
         # Boot order
         @boot_order = [] if @boot_order == UNSET_VALUE
 
         # Storage
         @disks = [] if @disks == UNSET_VALUE
         @cdroms = [] if @cdroms == UNSET_VALUE
+        @inputs = [{:type => "mouse", :bus => "ps2"}] if @inputs == UNSET_VALUE
       end
 
       def validate(machine)
diff --git a/lib/vagrant-libvirt/driver.rb b/lib/vagrant-libvirt/driver.rb
new file mode 100644
index 0000000..fe7a03e
--- /dev/null
+++ b/lib/vagrant-libvirt/driver.rb
@@ -0,0 +1,121 @@
+require 'fog/libvirt'
+require 'log4r'
+
+module VagrantPlugins
+  module ProviderLibvirt
+    class Driver
+
+      # store the connection at the process level
+      #
+      # possibly this should be a connection pool using the connection
+      # settings as a key to allow per machine connection attributes
+      # to be used.
+      @@connection = nil
+
+      def initialize(machine)
+        @logger = Log4r::Logger.new('vagrant_libvirt::driver')
+        @machine = machine
+      end
+
+      def connection
+        # If already connected to libvirt, just use it and don't connect
+        # again.
+        return @@connection if @@connection
+
+        # Get config options for libvirt provider.
+        config = @machine.provider_config
+        uri = config.uri
+
+        conn_attr = {}
+        conn_attr[:provider] = 'libvirt'
+        conn_attr[:libvirt_uri] = uri
+        conn_attr[:libvirt_username] = config.username if config.username
+        conn_attr[:libvirt_password] = config.password if config.password
+
+        # Setup command for retrieving IP address for newly created machine
+        # with some MAC address. Get it from dnsmasq leases table
+        ip_command = %q[ awk "/$mac/ {print \$1}" /proc/net/arp ]
+        conn_attr[:libvirt_ip_command] = ip_command
+
+        @logger.info("Connecting to Libvirt (#{uri}) ...")
+        begin
+          @@connection = Fog::Compute.new(conn_attr)
+        rescue Fog::Errors::Error => e
+          raise Errors::FogLibvirtConnectionError,
+            :error_message => e.message
+        end
+
+        @@connection
+      end
+
+      def get_domain(mid)
+        begin
+          domain = connection.servers.get(mid)
+        rescue Libvirt::RetrieveError => e
+          if e.libvirt_code == ProviderLibvirt::Util::ErrorCodes::VIR_ERR_NO_DOMAIN
+            @logger.debug("machine #{mid} not found #{e}.")
+            return nil
+          else
+            raise e
+          end
+        end
+
+        domain
+      end
+
+      def created?(mid)
+        domain = get_domain(mid)
+        !domain.nil?
+      end
+
+      def get_ipaddress(machine)
+        # Find the machine
+        domain = get_domain(machine.id)
+
+        if domain.nil?
+          # The machine can't be found
+          return nil
+        end
+
+        # Get IP address from arp table
+        ip_address = nil
+        begin
+          domain.wait_for(2) do
+            addresses.each_pair do |type, ip|
+              # Multiple leases are separated with a newline, return only
+              # the most recent address
+              ip_address = ip[0].split("\n").first if ip[0] != nil
+            end
+            ip_address != nil
+          end
+        rescue Fog::Errors::TimeoutError
+          @logger.info("Timeout at waiting for an ip address for machine %s" % machine.name)
+        end
+
+        if not ip_address
+          @logger.info("No arp table entry found for machine %s" % machine.name)
+          return nil
+        end
+
+        ip_address
+      end
+
+      def state(machine)
+        # may be other error states with initial retreival we can't handle
+        begin
+          domain = get_domain(machine.id)
+        rescue Libvirt::RetrieveError => e
+          @logger.debug("Machine #{machine.id} not found #{e}.")
+          return :not_created
+        end
+
+        # TODO: terminated no longer appears to be a valid fog state, remove?
+        if domain.nil? || domain.state.to_sym == :terminated
+          return :not_created
+        end
+
+        return domain.state.gsub("-", "_").to_sym
+      end
+    end
+  end
+end
diff --git a/lib/vagrant-libvirt/errors.rb b/lib/vagrant-libvirt/errors.rb
index 870c647..55bb33e 100644
--- a/lib/vagrant-libvirt/errors.rb
+++ b/lib/vagrant-libvirt/errors.rb
@@ -106,6 +106,10 @@ module VagrantPlugins
         error_key(:activate_network_error)
       end
 
+      class TunnelPortNotDefined < VagrantLibvirtError
+        error_key(:tunnel_port_not_defined)
+      end
+
       # Other exceptions
       class InterfaceSlotNotAvailable < VagrantLibvirtError
         error_key(:interface_slot_not_available)
diff --git a/lib/vagrant-libvirt/plugin.rb b/lib/vagrant-libvirt/plugin.rb
index 1dbb56c..f624cd5 100644
--- a/lib/vagrant-libvirt/plugin.rb
+++ b/lib/vagrant-libvirt/plugin.rb
@@ -23,11 +23,7 @@ module VagrantPlugins
         Config
       end
 
-      provider('libvirt', parallel: true) do
-        # Setup logging and i18n
-        setup_logging
-        setup_i18n
-
+      provider('libvirt', parallel: true, box_optional: true) do
         require_relative 'provider'
         Provider
       end
@@ -90,6 +86,12 @@ module VagrantPlugins
         end
       end
 
+      # Setup logging and i18n before any autoloading loads other classes
+      # with logging configured as this prevents inheritance of the log level
+      # from the parent logger.
+      setup_logging
+      setup_i18n
+
     end
   end
 end
diff --git a/lib/vagrant-libvirt/provider.rb b/lib/vagrant-libvirt/provider.rb
index 9420dc2..865edda 100644
--- a/lib/vagrant-libvirt/provider.rb
+++ b/lib/vagrant-libvirt/provider.rb
@@ -2,6 +2,7 @@ require 'vagrant'
 
 module VagrantPlugins
   module ProviderLibvirt
+    autoload :Driver, 'vagrant-libvirt/driver'
 
     # This is the base class for a provider for the V2 API. A provider
     # is responsible for creating compute resources to match the
@@ -22,6 +23,12 @@ module VagrantPlugins
         nil
       end
 
+      def driver
+        return @driver if @driver
+
+        @driver = Driver.new(@machine)
+      end
+
       # This method is called if the underying machine ID changes. Providers
       # can use this method to load in new data for the actual backing
       # machine or to realize that the machine is now gone (the ID can
@@ -33,9 +40,8 @@ module VagrantPlugins
       # SSH into the machine. If the machine is not at a point where
       # SSH is even possible, then `nil` should be returned.
       def ssh_info
-        # Run a custom action called "read_ssh_info" which does what it says
-        # and puts the resulting SSH info into the `:machine_ssh_info` key in
-        # the environment.
+        # Return the ssh_info if already retrieved otherwise call the driver
+        # and save the result.
         #
         # Ssh info has following format..
         #
@@ -45,8 +51,32 @@ module VagrantPlugins
         #  :username => "mitchellh",
         #  :private_key_path => "/path/to/my/key"
         #}
-        env = @machine.action('read_ssh_info')
-        env[:machine_ssh_info]
+        # note that modifing @machine.id or accessing @machine.state is not
+        # thread safe, so be careful to avoid these here as this method may
+        # be called from other threads of execution.
+        return nil if state.id != :running
+
+        ip = driver.get_ipaddress(@machine)
+
+        # if can't determine the IP, just return nil and let the core
+        # deal with it, similar to the docker provider
+        return nil if !ip
+
+        ssh_info = {
+          :host          => ip,
+          :port          => @machine.config.ssh.guest_port,
+          :forward_agent => @machine.config.ssh.forward_agent,
+          :forward_x11   => @machine.config.ssh.forward_x11,
+        }
+
+        ssh_info[:proxy_command] = (
+          "ssh '#{@machine.provider_config.host}' " +
+          "-l '#{@machine.provider_config.username}' " +
+          "-i '#{@machine.provider_config.id_ssh_key_file}' " +
+          "nc %h %p"
+        ) if @machine.provider_config.connect_via_ssh
+
+        ssh_info
       end
 
       def mac_addresses
@@ -64,16 +94,28 @@ module VagrantPlugins
       # This should return the state of the machine within this provider.
       # The state must be an instance of {MachineState}.
       def state
-        # Run a custom action we define called "read_state" which does
-        # what it says. It puts the state in the `:machine_state_id`
-        # key in the environment.
-        env = @machine.action('read_state')
 
-        state_id = env[:machine_state_id]
+        state_id = nil
+        state_id = :not_created if !@machine.id
+        state_id = :not_created if (
+          !state_id && (!@machine.id || !driver.created?(@machine.id)))
+        # Query the driver for the current state of the machine
+        state_id = driver.state(@machine) if @machine.id && !state_id
+        state_id = :unknown if !state_id
+
+        # This is a special pseudo-state so that we don't set the
+        # NOT_CREATED_ID while we're setting up the machine. This avoids
+        # clearing the data dir.
+        state_id = :preparing if @machine.id == "preparing"
 
         # Get the short and long description
-        short = I18n.t("vagrant_libvirt.states.short_#{state_id}")
-        long  = I18n.t("vagrant_libvirt.states.long_#{state_id}")
+        short = state_id.to_s.gsub("_", " ")
+        long  = I18n.t("vagrant_libvirt.states.#{state_id}")
+
+        # If we're not created, then specify the special ID flag
+        if state_id == :not_created
+          state_id = Vagrant::MachineState::NOT_CREATED_ID
+        end
 
         # Return the MachineState object
         Vagrant::MachineState.new(state_id, short, long)
diff --git a/lib/vagrant-libvirt/templates/domain.xml.erb b/lib/vagrant-libvirt/templates/domain.xml.erb
index e1264fb..cb87975 100644
--- a/lib/vagrant-libvirt/templates/domain.xml.erb
+++ b/lib/vagrant-libvirt/templates/domain.xml.erb
@@ -3,15 +3,17 @@
   <memory><%= @memory_size %></memory>
   <vcpu><%= @cpus %></vcpu>
 
-  <% if @nested %>
-    <cpu mode='<%= @cpu_mode %>'>
-      <% if @cpu_mode != 'host-passthrough' %>
-        <model fallback='allow'>qemu64</model>
+
+  <cpu mode='<%= @cpu_mode %>'>
+    <% if @cpu_mode != 'host-passthrough' %>
+      <model fallback='allow'>qemu64</model>
+      <% if @nested %>
         <feature policy='optional' name='vmx'/>
         <feature policy='optional' name='svm'/>
       <% end %>
-    </cpu>
-  <% end %>
+    <% end %>
+  </cpu>
+
 
   <os>
     <% if @machine_type %>
@@ -27,13 +29,11 @@
         <type>hvm</type>
       <% end %>
     <% end %>
+    <% if @loader %>
+      <loader readonly='yes' type='rom'><%= @loader %></loader>
+    <% end %>
     <% if @boot_order.count >= 1 %>
-      <% @boot_order.each do |b| %>
-        <boot dev='<%= b %>'/>
-      <% end %> 
       <bootmenu enable='yes'/>
-    <% else %>
-      <boot dev='hd' />
     <% end %>
     <kernel><%= @kernel %></kernel>
     <initrd><%= @initrd %></initrd>
@@ -46,12 +46,14 @@
   </features>
   <clock offset='utc'/>
   <devices>
+    <% if @domain_volume_path %>
     <disk type='file' device='disk'>
       <driver name='qemu' type='qcow2' cache='<%= @domain_volume_cache %>'/>
       <source file='<%= @domain_volume_path %>'/>
       <%# we need to ensure a unique target dev -%>
       <target dev='vda' bus='<%= @disk_bus %>'/>
     </disk>
+    <% end %>
 <%# additional disks -%>
 <% @disks.each do |d| -%>
     <disk type='file' device='disk'>
@@ -78,7 +80,11 @@
     <console type='pty'>
       <target port='0'/>
     </console>
-    <input type='mouse' bus='ps2'/>
+
+<% @inputs.each do |input| %>
+    <input type='<%= input[:type] %>' bus='<%= input[:bus] %>'/>
+<% end %>
+
     <%# Video device -%>
     <graphics type='<%= @graphics_type %>' port='<%= @graphics_port %>' autoport='<%= @graphics_autoport %>' listen='<%= @graphics_ip %>' keymap='<%= @keymap %>' <%= @graphics_passwd%> />
       <video>
diff --git a/lib/vagrant-libvirt/templates/filesystem.xml.erb b/lib/vagrant-libvirt/templates/filesystem.xml.erb
index d0a35c9..a9824e4 100644
--- a/lib/vagrant-libvirt/templates/filesystem.xml.erb
+++ b/lib/vagrant-libvirt/templates/filesystem.xml.erb
@@ -1,7 +1,7 @@
     <filesystem type='mount' accessmode='<%= accessmode %>'>
       <driver type='path' wrpolicy='immediate'/>
       <source dir='<%= hostpath %>'/>
-      <target dir='<%= target %>'/>
+      <target dir='<%= mount_tag %>'/>
       <% unless readonly.nil? %>
          <readonly /> 
       <% end %>
diff --git a/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb b/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb
new file mode 100644
index 0000000..315e1be
--- /dev/null
+++ b/lib/vagrant-libvirt/templates/tunnel_interface.xml.erb
@@ -0,0 +1,11 @@
+<interface type='<%= @type %>'>
+  <% if @mac %>
+  <mac address='<%= @mac %>'/>
+  <% end %>
+  <source address='<%=@tunnel_ip%>' port='<%= @tunnel_port %>'>
+  <% if @type == 'udp' %>
+    <local address='<%=@udp_tunnel_local_ip%>' port='<%=@udp_tunnel_local_port%>' />
+  <% end %>
+  </source>
+  <model type='<%=@model_type%>'/>
+</interface>
diff --git a/lib/vagrant-libvirt/util/network_util.rb b/lib/vagrant-libvirt/util/network_util.rb
index dea45d5..9777e6d 100644
--- a/lib/vagrant-libvirt/util/network_util.rb
+++ b/lib/vagrant-libvirt/util/network_util.rb
@@ -10,7 +10,8 @@ module VagrantPlugins
         def configured_networks(env, logger)
           management_network_name = env[:machine].provider_config.management_network_name
           management_network_address = env[:machine].provider_config.management_network_address
-          management_network_mode = env[:machine].provider_config.management_network_mode 
+          management_network_mode = env[:machine].provider_config.management_network_mode
+          management_network_mac = env[:machine].provider_config.management_network_mac
           logger.info "Using #{management_network_name} at #{management_network_address} as the management network #{management_network_mode} is the mode"
 
           begin
@@ -37,6 +38,10 @@ module VagrantPlugins
             forward_mode: management_network_mode,
           }
 
+          unless management_network_mac.nil?
+            management_network_options[:mac] = management_network_mac
+          end
+
           # add management network to list of networks to check
           networks = [ management_network_options ]
 
@@ -54,6 +59,11 @@ module VagrantPlugins
               dhcp_enabled: true,
               forward_mode: 'nat',
             }.merge(options)
+
+            if options[:type].to_s == 'dhcp' && options[:ip].nil?
+              options[:network_name] = "vagrant-private-dhcp"
+            end
+
             # add to list of networks to check
             networks.push(options)
           end
diff --git a/lib/vagrant-libvirt/version.rb b/lib/vagrant-libvirt/version.rb
index e29adef..c6b0c92 100644
--- a/lib/vagrant-libvirt/version.rb
+++ b/lib/vagrant-libvirt/version.rb
@@ -1,5 +1,5 @@
 module VagrantPlugins
   module ProviderLibvirt
-    VERSION = '0.0.30'
+    VERSION = '0.0.31'
   end
 end
diff --git a/locales/en.yml b/locales/en.yml
index 7118fd9..30a853e 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -12,6 +12,9 @@ en:
       Checking if volume is available.
     creating_domain: |-
       Creating domain with the following settings...
+    manual_resize_required: |-
+      Created volume larger than box defaults, will require manual resizing of
+      filesystems to utilize.
     uploading_volume: |-
       Uploading base box image as volume into libvirt storage...
     creating_domain_volume: |-
@@ -47,8 +50,13 @@ en:
     remove_stale_volume: |-
       Remove stale volume...
 
+    warnings:
+      ignoring_virtual_size_too_small: |-
+        Ignoring requested virtual disk size of '%{requested}' as it is below
+        the minimum box image size of '%{box_virtual_size}'.
+
     errors:
-      package_not_supported: Not support package for libvirt. Create box manualy.
+      package_not_supported: No support for package with libvirt. Create box manually.
       fog_error: |-
         There was an error talking to Libvirt. The error message is shown
         below:
@@ -71,7 +79,7 @@ en:
         Interface adapter number is already in use. Please specify other adapter
         number.
       rsync_error: |-
-        There was an error when attemping to rsync a share folder.
+        There was an error when attempting to rsync a share folder.
         Please inspect the error message below for more info.
 
         Host path: %{hostpath}
@@ -115,7 +123,7 @@ en:
         Network %{network_name} exists but does not have dhcp %{requested}.
         Please fix your configuration and run vagrant again.
       create_network_error: |-
-        Error occured while creating new network: %{error_message}.
+        Error occurred while creating new network: %{error_message}.
       network_not_available_error: |-
         Network %{network_name} is not available. Specify available network
         name, or an ip address if you want to create a new network.
@@ -127,21 +135,22 @@ en:
         Error while removing network %{network_name}. %{error_message}.
       delete_snapshot_error: |-
         Error while deleting snapshot: %{error_message}.
+      tunnel_port_not_defined: |-
+         tunnel UDP or TCP port not defined.
 
     states:
-      short_paused: |-
-        pause
-      short_shutoff: |-
-        shutoff
-      long_shutoff: |-
+      paused: |-
+        The Libvirt domain is suspended. Run `vagrant resume` to resume it.
+      shutting_down: |-
+        The Libvirt domain is shutting down. Wait for it to complete and
+        then run `vagrant up` to start it or `vagrant destroy` to remove.
+      shutoff: |-
         The Libvirt domain is not running. Run `vagrant up` to start it.
-      short_not_created: |-
-        not created
-      long_not_created: |-
+      not_created: |-
         The Libvirt domain is not created. Run `vagrant up` to create it.
-
-      short_running: |-
-        running
-      long_running: |-
+      running: |-
         The Libvirt domain is running. To stop this machine, you can run
         `vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
+      preparing: |-
+        The vagrant machine is being prepared for creation, please wait for
+        it to reach a steady state before issuing commands on it.
diff --git a/metadata.yml b/metadata.yml
index 72c62a3..790ad9b 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,7 +1,7 @@
 --- !ruby/object:Gem::Specification
 name: vagrant-libvirt
 version: !ruby/object:Gem::Version
-  version: 0.0.30
+  version: 0.0.31
 platform: ruby
 authors:
 - Lukas Stanek
@@ -10,7 +10,7 @@ authors:
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2015-06-04 00:00:00.000000000 Z
+date: 2015-09-25 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rspec-core
@@ -106,6 +106,7 @@ extensions: []
 extra_rdoc_files: []
 files:
 - ".gitignore"
+- ".travis.yml"
 - CHANGELOG.md
 - Gemfile
 - LICENSE
@@ -116,7 +117,6 @@ files:
 - example_box/metadata.json
 - lib/vagrant-libvirt.rb
 - lib/vagrant-libvirt/action.rb
-- lib/vagrant-libvirt/action/connect_libvirt.rb
 - lib/vagrant-libvirt/action/create_domain.rb
 - lib/vagrant-libvirt/action/create_domain_volume.rb
 - lib/vagrant-libvirt/action/create_network_interfaces.rb
@@ -139,11 +139,10 @@ files:
 - lib/vagrant-libvirt/action/prepare_nfs_valid_ids.rb
 - lib/vagrant-libvirt/action/prune_nfs_exports.rb
 - lib/vagrant-libvirt/action/read_mac_addresses.rb
-- lib/vagrant-libvirt/action/read_ssh_info.rb
-- lib/vagrant-libvirt/action/read_state.rb
 - lib/vagrant-libvirt/action/remove_libvirt_image.rb
 - lib/vagrant-libvirt/action/remove_stale_volume.rb
 - lib/vagrant-libvirt/action/resume_domain.rb
+- lib/vagrant-libvirt/action/set_boot_order.rb
 - lib/vagrant-libvirt/action/set_name_of_domain.rb
 - lib/vagrant-libvirt/action/share_folders.rb
 - lib/vagrant-libvirt/action/start_domain.rb
@@ -153,6 +152,7 @@ files:
 - lib/vagrant-libvirt/cap/nic_mac_addresses.rb
 - lib/vagrant-libvirt/cap/synced_folder.rb
 - lib/vagrant-libvirt/config.rb
+- lib/vagrant-libvirt/driver.rb
 - lib/vagrant-libvirt/errors.rb
 - lib/vagrant-libvirt/plugin.rb
 - lib/vagrant-libvirt/provider.rb
@@ -162,6 +162,7 @@ files:
 - lib/vagrant-libvirt/templates/interface.xml.erb
 - lib/vagrant-libvirt/templates/private_network.xml.erb
 - lib/vagrant-libvirt/templates/public_interface.xml.erb
+- lib/vagrant-libvirt/templates/tunnel_interface.xml.erb
 - lib/vagrant-libvirt/templates/volume_snapshot.xml.erb
 - lib/vagrant-libvirt/util.rb
 - lib/vagrant-libvirt/util/collection.rb
diff --git a/spec/support/environment_helper.rb b/spec/support/environment_helper.rb
index ddfa43b..e362d88 100644
--- a/spec/support/environment_helper.rb
+++ b/spec/support/environment_helper.rb
@@ -19,7 +19,7 @@ class EnvironmentHelper
     1024
   end
 
-  %w(cpus cpu_mode boot_order machine_type disk_bus nested volume_cache kernel cmd_line initrd graphics_type graphics_autoport graphics_port graphics_ip graphics_passwd video_type video_vram keymap storage_pool_name disks cdroms driver).each do |name|
+  %w(cpus cpu_mode loader boot_order machine_type disk_bus nested volume_cache kernel cmd_line initrd graphics_type graphics_autoport graphics_port graphics_ip graphics_passwd video_type video_vram keymap storage_pool_name disks cdroms driver).each do |name|
     define_method(name.to_sym) do
       nil
     end
diff --git a/tools/prepare_redhat_for_box.sh b/tools/prepare_redhat_for_box.sh
index 1f0cf8c..e9ffb39 100755
--- a/tools/prepare_redhat_for_box.sh
+++ b/tools/prepare_redhat_for_box.sh
@@ -54,8 +54,6 @@ rm -f ~root/${EPEL_PKG}
 yum -y install openssh-server openssh-clients sudo \
 ruby ruby-devel make gcc rubygems rsync
 chkconfig sshd on
-gem install puppet
-gem install chef
 
 
 # Users, groups, passwords and sudoers.
@@ -118,3 +116,4 @@ rm -f ~root/.bash_history
 rm -r "$(gem env gemdir)"/doc/*
 yum clean all
 
+halt

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/vagrant-libvirt.git



More information about the Pkg-ruby-extras-commits mailing list