vagrant-bhyve 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +13 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +111 -0
  8. data/Rakefile +6 -0
  9. data/Vagrantfiles/Vagrantfile_CentOS-6 +14 -0
  10. data/Vagrantfiles/Vagrantfile_CentOS-7 +11 -0
  11. data/Vagrantfiles/Vagrantfile_Debian_Ubuntu +11 -0
  12. data/example_box/README.md +46 -0
  13. data/example_box/Vagrantfile +9 -0
  14. data/example_box/metadata.json +3 -0
  15. data/lib/vagrant-bhyve.rb +21 -0
  16. data/lib/vagrant-bhyve/action.rb +215 -0
  17. data/lib/vagrant-bhyve/action/boot.rb +26 -0
  18. data/lib/vagrant-bhyve/action/cleanup.rb +23 -0
  19. data/lib/vagrant-bhyve/action/create_bridge.rb +33 -0
  20. data/lib/vagrant-bhyve/action/create_tap.rb +31 -0
  21. data/lib/vagrant-bhyve/action/destroy.rb +23 -0
  22. data/lib/vagrant-bhyve/action/forward_ports.rb +53 -0
  23. data/lib/vagrant-bhyve/action/import.rb +32 -0
  24. data/lib/vagrant-bhyve/action/load.rb +27 -0
  25. data/lib/vagrant-bhyve/action/prepare_nfs_settings.rb +50 -0
  26. data/lib/vagrant-bhyve/action/prepare_nfs_valid_ids.rb +23 -0
  27. data/lib/vagrant-bhyve/action/setup.rb +27 -0
  28. data/lib/vagrant-bhyve/action/shutdown.rb +26 -0
  29. data/lib/vagrant-bhyve/action/wait_until_up.rb +48 -0
  30. data/lib/vagrant-bhyve/config.rb +75 -0
  31. data/lib/vagrant-bhyve/driver.rb +674 -0
  32. data/lib/vagrant-bhyve/errors.rb +55 -0
  33. data/lib/vagrant-bhyve/executor.rb +38 -0
  34. data/lib/vagrant-bhyve/plugin.rb +73 -0
  35. data/lib/vagrant-bhyve/provider.rb +126 -0
  36. data/lib/vagrant-bhyve/version.rb +5 -0
  37. data/locales/en.yml +90 -0
  38. data/vagrant-bhyve.gemspec +24 -0
  39. metadata +137 -0
@@ -0,0 +1,26 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Boot
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::boot")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @driver = @machine.provider.driver
16
+
17
+ env[:ui].detail I18n.t('vagrant_bhyve.action.vm.boot.booting')
18
+ @driver.boot(@machine, env[:ui])
19
+
20
+ @app.call(env)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Cleanup
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::cleanup")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.halt.cleaning_up')
15
+ env[:machine].provider.driver.cleanup
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class CreateBridge
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::create_bridge")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @ui = env[:ui]
16
+ @driver = @machine.provider.driver
17
+
18
+ @ui.info I18n.t('vagrant.actions.vm.boot.booting')
19
+ @ui.detail I18n.t('vagrant_bhyve.action.vm.boot.setup_nat')
20
+
21
+ bridge_list = %w(vagrant_bhyve_default_bridge)
22
+ # The bridge name is used as created bridge device's description
23
+ bridge_list.each do |bridge|
24
+ @driver.create_network_device(bridge, "bridge")
25
+ @driver.enable_nat(bridge, @ui)
26
+ end
27
+ @app.call(env)
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,31 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class CreateTap
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::create_tap")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @driver = @machine.provider.driver
16
+
17
+ env[:ui].detail I18n.t('vagrant_bhyve.action.vm.boot.create_tap')
18
+ vm_name = @driver.get_attr('vm_name')
19
+ tap_name = "vagrant_bhyve_#{vm_name}"
20
+ tap_list = [tap_name]
21
+ # The switch name is used as created bridge device's description
22
+ tap_list.each do |tap|
23
+ @driver.create_network_device(tap, "tap")
24
+ end
25
+ @app.call(env)
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Destroy
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::destroy")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.destroying')
15
+ env[:machine].provider.driver.destroy
16
+
17
+ @app.call(env)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,53 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class ForwardPorts
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::forward_ports")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @driver = @machine.provider.driver
16
+
17
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.forward_ports')
18
+
19
+ env[:forwarded_ports] = compile_forwarded_ports(@machine.config)
20
+ tap_device = @driver.get_attr('tap')
21
+ gateway = @driver.get_attr('gateway')
22
+ env[:forwarded_ports].each do |item|
23
+ forward_information = {
24
+ adapter: item[:adapter] || gateway,
25
+ guest_port: item[:guest],
26
+ host_port: item[:host]
27
+ }
28
+ @driver.forward_port(forward_information, tap_device)
29
+ end
30
+ @app.call(env)
31
+ end
32
+
33
+ private
34
+
35
+ def compile_forwarded_ports(config)
36
+ mappings = {}
37
+ config.vm.networks.each do |type, options|
38
+ next if options[:disabled]
39
+
40
+ if type == :forwarded_port && options[:id] != 'ssh'
41
+ if options.fetch(:host_ip, '').to_s.strip.empty?
42
+ options.delete(:host_ip)
43
+ end
44
+ mappings[options[:host]] = options
45
+ end
46
+ end
47
+ mappings.values
48
+
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,32 @@
1
+ require "log4r"
2
+ require "securerandom"
3
+ require "digest/md5"
4
+
5
+ module VagrantPlugins
6
+ module ProviderBhyve
7
+ module Action
8
+ class Import
9
+
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::import")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ @machine = env[:machine]
17
+ @driver = @machine.provider.driver
18
+
19
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.import_box')
20
+ @machine.id = SecureRandom.uuid
21
+ vm_name = @machine.id.gsub('-', '')[0..30]
22
+ mac = @driver.get_mac_address(vm_name)
23
+ @driver.store_attr('vm_name', vm_name)
24
+ @driver.store_attr('mac', mac)
25
+ @driver.import(@machine, env[:ui])
26
+ @app.call(env)
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Load
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::load")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @driver = @machine.provider.driver
16
+ firmware = @driver.get_attr('firmware')
17
+
18
+ env[:ui].detail I18n.t('vagrant_bhyve.action.vm.boot.load_kernel')
19
+ @driver.load(@machine, env[:ui]) if firmware == 'bios'
20
+
21
+ @app.call(env)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+ require "log4r"
2
+ require "securerandom"
3
+ require "digest/md5"
4
+
5
+ module VagrantPlugins
6
+ module ProviderBhyve
7
+ module Action
8
+ class PrepareNFSSettings
9
+ include Vagrant::Action::Builtin::MixinSyncedFolders
10
+
11
+ def initialize(app, env)
12
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::prepare_nfs_settings")
13
+ @app = app
14
+ end
15
+
16
+ def call(env)
17
+ @machine = env[:machine]
18
+ @driver = @machine.provider.driver
19
+ @app.call(env)
20
+
21
+ if using_nfs?
22
+ tap_device = @driver.get_attr('tap')
23
+ #host_ip = @driver.get_ip_address(nil, :host)
24
+ guest_ip = @driver.get_ip_address(tap_device, :guest)
25
+ host_ip = read_host_ip(guest_ip)
26
+ env[:nfs_machine_ip] = guest_ip
27
+ env[:nfs_host_ip] = host_ip
28
+ end
29
+ end
30
+
31
+ def using_nfs?
32
+ !!synced_folders(@machine)[:nfs]
33
+ end
34
+
35
+ # Ruby way to get host ip
36
+ def read_host_ip(ip)
37
+ UDPSocket.open do |s|
38
+ if(ip.kind_of?(Array))
39
+ s.connect(ip.last, 1)
40
+ else
41
+ s.connect(ip, 1)
42
+ end
43
+ s.addr.last
44
+ end
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ require "log4r"
2
+ require "securerandom"
3
+ require "digest/md5"
4
+
5
+ module VagrantPlugins
6
+ module ProviderBhyve
7
+ module Action
8
+ class PrepareNFSValidIds
9
+
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::prepare_nfs_valid_ids")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ env[:nfs_valid_ids] = [env[:machine].id]
17
+ @app.call(env)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,27 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Setup
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::setup")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @driver = env[:machine].provider.driver
15
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.setup_environment')
16
+ @driver.check_bhyve_support
17
+ module_list = %w(vmm nmdm if_bridge if_tap pf)
18
+ for kernel_module in module_list
19
+ @driver.load_module(kernel_module)
20
+ end
21
+ @app.call(env)
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ module Action
6
+ class Shutdown
7
+
8
+ def initialize(app, env)
9
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::shutdown")
10
+ @app = app
11
+ end
12
+
13
+ def call(env)
14
+ @machine = env[:machine]
15
+ @ui = env[:ui]
16
+ @driver = @machine.provider.driver
17
+
18
+ @ui.info I18n.t('vagrant_bhyve.action.vm.halt.shutting_down')
19
+ @driver.shutdown(@ui)
20
+ @app.call(env)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ require "log4r"
2
+ require "vagrant/util/retryable"
3
+
4
+ module VagrantPlugins
5
+ module ProviderBhyve
6
+ module Action
7
+ class WaitUntilUP
8
+ include Vagrant::Util::Retryable
9
+
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant_bhyve::action::wait_until_up")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ @driver = env[:machine].provider.driver
17
+ env[:ui].info I18n.t('vagrant_bhyve.action.vm.boot.wait_until_up')
18
+
19
+ vm_name = @driver.get_attr('vm_name')
20
+ # Check whether ip is assigned
21
+ env[:uncleaned] = false
22
+ while !env[:uncleaned]
23
+ sleep 1
24
+ env[:uncleaned] = true if @driver.state(vm_name) == :uncleaned
25
+ if @driver.ip_ready?
26
+ sleep 2
27
+ env[:uncleaned] = true if @driver.state(vm_name) == :uncleaned
28
+ break
29
+ end
30
+ end
31
+
32
+ # Check whether we have ssh access
33
+ while !env[:uncleaned]
34
+ sleep 1
35
+ env[:uncleaned] = true if @driver.state(vm_name) == :uncleaned
36
+ if @driver.ssh_ready?(env[:machine].provider.ssh_info)
37
+ sleep 2
38
+ env[:uncleaned] = true if @driver.state(vm_name) == :uncleaned
39
+ break
40
+ end
41
+ end
42
+ @app.call(env)
43
+ end
44
+
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,75 @@
1
+ require "vagrant"
2
+
3
+ module VagrantPlugins
4
+ module ProviderBhyve
5
+ class Config < Vagrant.plugin('2', :config)
6
+
7
+ # Guest like CentOS-6 requires a customized grub config file
8
+ #attr_accessor :grub_config_file
9
+
10
+ # Some arguments required by grub-bhyve
11
+ #attr_accessor :grub_run_partition
12
+ #attr_accessor :grub_run_dir
13
+
14
+ # Specify the number of virtual CPUs.
15
+ attr_accessor :cpus
16
+ # Specify the size of guest physical memory.
17
+ attr_accessor :memory
18
+ # Specify virtual devices will be attached to bhyve's emulated
19
+ # PCI bus. Network interface and disk will both attched as this kind
20
+ # of devices.
21
+ attr_accessor :pcis
22
+ # Specify console device which will be attached to the VM
23
+ attr_accessor :lpc
24
+ attr_accessor :hostbridge
25
+ # Addition storage
26
+ attr_accessor :disks
27
+ attr_accessor :cdroms
28
+
29
+ def initialize
30
+ @cpus = UNSET_VALUE
31
+ @memory = UNSET_VALUE
32
+ @pcis = UNSET_VALUE
33
+ @lpc = UNSET_VALUE
34
+ @hostbridge = UNSET_VALUE
35
+ @disks = []
36
+ @cdroms = []
37
+ #@grub_config_file = ''
38
+ #@grub_run_partition = ''
39
+ #@grub_run_dir = ''
40
+ end
41
+
42
+ def storage(options={})
43
+ if options[:device] == :cdrom
44
+ _handle_cdrom_storage(options)
45
+ elsif options[:device] == :disk
46
+ _handle_disk_storage(options)
47
+ end
48
+ end
49
+
50
+ def _handle_disk_storage(options={})
51
+ cdrom = {
52
+ path: options[:path]
53
+ }
54
+ @cdroms << cdrom
55
+ end
56
+
57
+ def _handle_cdrom_storage(options={})
58
+ options = {
59
+ path: nil,
60
+ name: nil,
61
+ size: "20G",
62
+ format: "raw",
63
+ }.merge(options)
64
+
65
+ disk = {
66
+ path: options[:path],
67
+ size: options[:size],
68
+ }
69
+
70
+ @disks << disk
71
+ end
72
+
73
+ end
74
+ end
75
+ end