vagrant-xhyve 0.1.1 → 0.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/Gemfile +1 -0
- data/README.md +6 -0
- data/lib/vagrant-xhyve/action/boot.rb +3 -1
- data/lib/vagrant-xhyve/config.rb +14 -5
- data/lib/vagrant-xhyve/util/vagrant-xhyve.rb +22 -1
- data/lib/vagrant-xhyve/version.rb +1 -1
- data/vendor/xhyve-ruby/.gitignore +8 -0
- data/vendor/xhyve-ruby/.travis.yml +10 -0
- data/vendor/xhyve-ruby/Gemfile +3 -0
- data/vendor/xhyve-ruby/README.md +33 -0
- data/vendor/xhyve-ruby/Rakefile +42 -0
- data/vendor/xhyve-ruby/example/test.rb +17 -0
- data/vendor/xhyve-ruby/lib/rubygems_plugin.rb +7 -0
- data/vendor/xhyve-ruby/lib/xhyve.rb +4 -0
- data/vendor/xhyve-ruby/lib/xhyve/dhcp.rb +41 -0
- data/vendor/xhyve-ruby/lib/xhyve/guest.rb +88 -0
- data/vendor/xhyve-ruby/lib/xhyve/vendor/xhyve +0 -0
- data/vendor/xhyve-ruby/lib/xhyve/version.rb +4 -0
- data/vendor/xhyve-ruby/spec/fixtures/dhcpd_leases.txt +35 -0
- data/vendor/xhyve-ruby/spec/fixtures/guest/README.md +33 -0
- data/vendor/xhyve-ruby/spec/fixtures/guest/initrd +0 -0
- data/vendor/xhyve-ruby/spec/fixtures/guest/loop.img +0 -0
- data/vendor/xhyve-ruby/spec/fixtures/guest/vmlinuz +0 -0
- data/vendor/xhyve-ruby/spec/lib/dhcp_spec.rb +34 -0
- data/vendor/xhyve-ruby/spec/lib/guest_spec.rb +51 -0
- data/vendor/xhyve-ruby/spec/spec_helper.rb +52 -0
- data/vendor/xhyve-ruby/xhyve-ruby.gemspec +23 -0
- metadata +23 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 701f6d5e2381b33845d6908ec66a9c885fdb3560
|
4
|
+
data.tar.gz: 484ab4ecc0b48dcc2831424adb42bf41a33c2364
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f2c3171afe29035229dd8b280c4b0139773ae042d107a6a12205b0603ae8d5a9ee9b2f379a6f2e59a1529878003a415fc443612b78a05d57fed231d927d3f2be
|
7
|
+
data.tar.gz: 9c6673a0e8655de1fbcc76e66bf73a9095efb1a901cdad3eba435bebbcfecaba1d4dac6256c7798f0cf112fdec3443506da3701961bd252330df9897b72d50ee
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Vagrant xhyve Provider
|
2
2
|
|
3
|
+
[](https://badge.fury.io/rb/vagrant-xhyve)
|
4
|
+
|
3
5
|
This is a [Vagrant](http://www.vagrantup.com) plugin that adds an [xhyve](http://xhyve.org)
|
4
6
|
provider to Vagrant.
|
5
7
|
|
@@ -64,6 +66,9 @@ This provider exposes quite a few provider-specific configuration options:
|
|
64
66
|
integer for memory in MB or you can use the suffixed style, eg. 2G for two
|
65
67
|
Gigabytes
|
66
68
|
* `cpus` - The number of CPUs to give the VM
|
69
|
+
* `xhyve_binary` - use a custom xhyve version (for example, the version of xhyve
|
70
|
+
included with [Docker for Mac Beta](https://docs.docker.com/engine/installation/mac/#docker-for-mac)
|
71
|
+
is interesting. The path is `/Applications/Docker.app/Contents/MacOS/com.docker.hyperkit`
|
67
72
|
|
68
73
|
These can be set like typical provider-specific configuration:
|
69
74
|
|
@@ -74,6 +79,7 @@ Vagrant.configure("2") do |config|
|
|
74
79
|
config.vm.provider :xhyve do |xhyve|
|
75
80
|
xhyve.cpus = 2
|
76
81
|
xhyve.memory = "1G"
|
82
|
+
xhyve_xhyve_binary = "/Applications/Docker.app/Contents/MacOS/com.docker.hyperkit"
|
77
83
|
end
|
78
84
|
end
|
79
85
|
```
|
@@ -27,10 +27,12 @@ module VagrantPlugins
|
|
27
27
|
|
28
28
|
memory = env[:machine].provider_config.memory
|
29
29
|
cpus = env[:machine].provider_config.cpus
|
30
|
+
xhyve_binary = env[:machine].provider_config.xhyve_binary
|
30
31
|
|
31
32
|
# Launch!
|
32
33
|
env[:ui].info(" -- CPUs: #{cpus}") if cpus
|
33
34
|
env[:ui].info(" -- Memory: #{memory}")
|
35
|
+
env[:ui].info(" -- xhyve binary: #{xhyve_binary.to_s}") if xhyve_binary
|
34
36
|
|
35
37
|
machine_info_path = File.join(env[:machine].data_dir, "xhyve.json")
|
36
38
|
if File.exist?(machine_info_path) then
|
@@ -81,10 +83,10 @@ module VagrantPlugins
|
|
81
83
|
memory: memory,
|
82
84
|
processors: cpus,
|
83
85
|
networking: true,
|
86
|
+
xhyve_binary: xhyve_binary,
|
84
87
|
acpi: true
|
85
88
|
)
|
86
89
|
|
87
|
-
|
88
90
|
xhyve_pid = xhyve_guest.start
|
89
91
|
@logger.debug(xhyve_guest.options().to_json)
|
90
92
|
|
data/lib/vagrant-xhyve/config.rb
CHANGED
@@ -19,7 +19,14 @@ module VagrantPlugins
|
|
19
19
|
#
|
20
20
|
# @return [String]
|
21
21
|
attr_accessor :memory
|
22
|
-
|
22
|
+
|
23
|
+
|
24
|
+
# The path to the xhyve binary if you don't want to
|
25
|
+
# use the one bundled with xhyve-ruby
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
attr_accessor :xhyve_binary
|
29
|
+
|
23
30
|
# The mac address of the VM
|
24
31
|
#
|
25
32
|
# @return [String]
|
@@ -31,10 +38,11 @@ module VagrantPlugins
|
|
31
38
|
attr_accessor :uuid
|
32
39
|
|
33
40
|
def initialize(region_specific=false)
|
34
|
-
@cpus
|
35
|
-
@memory
|
36
|
-
@
|
37
|
-
@
|
41
|
+
@cpus = UNSET_VALUE
|
42
|
+
@memory = UNSET_VALUE
|
43
|
+
@xhyve_binary = UNSET_VALUE
|
44
|
+
@mac = UNSET_VALUE
|
45
|
+
@uuid = UNSET_VALUE
|
38
46
|
|
39
47
|
# Internal state (prefix with __ so they aren't automatically
|
40
48
|
# merged)
|
@@ -52,6 +60,7 @@ module VagrantPlugins
|
|
52
60
|
|
53
61
|
@cpus = 1 if @cpus == UNSET_VALUE
|
54
62
|
@memory = 1024 if @memory == UNSET_VALUE
|
63
|
+
@xhyve_binary = nil if @xhyve_binary == UNSET_VALUE
|
55
64
|
|
56
65
|
# Mark that we finalized
|
57
66
|
@__finalized = true
|
@@ -3,9 +3,12 @@ require 'xhyve'
|
|
3
3
|
module VagrantPlugins
|
4
4
|
module XHYVE
|
5
5
|
module Util
|
6
|
+
|
7
|
+
# TODO: send all this upstream
|
6
8
|
class XhyveGuest < Xhyve::Guest
|
7
9
|
|
8
10
|
def initialize(**opts)
|
11
|
+
@xhyve_binary = opts[:xhyve_binary] || Xhyve::BINARY_PATH
|
9
12
|
if opts.has_key? "pid"
|
10
13
|
@pid = pid
|
11
14
|
else
|
@@ -23,6 +26,7 @@ module VagrantPlugins
|
|
23
26
|
@command = build_command
|
24
27
|
@mac = find_mac
|
25
28
|
end
|
29
|
+
|
26
30
|
end
|
27
31
|
|
28
32
|
def options
|
@@ -41,9 +45,26 @@ module VagrantPlugins
|
|
41
45
|
:foreground => @foreground,
|
42
46
|
:command => @command,
|
43
47
|
:mac => @mac,
|
44
|
-
:ip => ip
|
48
|
+
:ip => ip,
|
49
|
+
:xhyve_binary => @xhyve_binary
|
45
50
|
}
|
46
51
|
end
|
52
|
+
|
53
|
+
def build_command
|
54
|
+
[
|
55
|
+
"#{@xhyve_binary}",
|
56
|
+
"#{'-A' if @acpi}",
|
57
|
+
'-U', @uuid,
|
58
|
+
'-m', @memory,
|
59
|
+
'-c', @processors,
|
60
|
+
'-s', '0:0,hostbridge',
|
61
|
+
"#{"-s #{PCI_BASE - 1}:0,virtio-net" if @networking }" ,
|
62
|
+
"#{"#{@blockdevs.each_with_index.map { |p, i| "-s #{PCI_BASE + i},virtio-blk,#{p}" }.join(' ')}" unless @blockdevs.empty? }",
|
63
|
+
'-s', '31,lpc',
|
64
|
+
'-l', "#{@serial},stdio",
|
65
|
+
'-f' "kexec,#{@kernel},#{@initrd},'#{@cmdline}'"
|
66
|
+
].join(' ')
|
67
|
+
end
|
47
68
|
end
|
48
69
|
end
|
49
70
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+

|
2
|
+
|
3
|
+
# Ruby Xhyve
|
4
|
+
|
5
|
+
This is a simple ruby-wrapper around [xhyve](https://github.com/mist64/xhyve), allowing you to start hypervisor Guests on OS-X
|
6
|
+
|
7
|
+
# Usage
|
8
|
+
|
9
|
+
You can run a guest fairly easily:
|
10
|
+
|
11
|
+
```
|
12
|
+
require 'xhyve'
|
13
|
+
|
14
|
+
guest = Xhyve::Guest.new(
|
15
|
+
kernel: 'guest/vmlinuz', # path to vmlinuz
|
16
|
+
initrd: 'guest/initrd', # path to initrd
|
17
|
+
cmdline: 'console=tty0', # boot flags to linux
|
18
|
+
blockdevs: 'loop.img', # path to img files to use as block devs
|
19
|
+
uuid: 'a-valid-uuid', # a valid UUID
|
20
|
+
serial: 'com2', # com1 / com2 (maps to ttyS0, ttyS1, etc)
|
21
|
+
memory: '200M', # amount of memory in M/G
|
22
|
+
processors: 1, # number of processors
|
23
|
+
networking: true, # Enable networking? (requires sudo)
|
24
|
+
acpi: true, # set up acpi? (required for clean shutdown)
|
25
|
+
)
|
26
|
+
|
27
|
+
pid = guest.start # starting the guest spawns an xhyve subprocess, returning the pid
|
28
|
+
guest.running? # is the guest running?
|
29
|
+
guest.ip # get the IP of the guest
|
30
|
+
guest.mac # get MAC address of the guest
|
31
|
+
guest.stop # stop the guest
|
32
|
+
guest.destroy # forcefully stop the guest
|
33
|
+
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rake/extensiontask'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
XHYVE_TMP = 'tmp/xhyve'
|
6
|
+
|
7
|
+
# Compile native extensions task
|
8
|
+
Rake::ExtensionTask.new 'vmnet' do |ext|
|
9
|
+
ext.lib_dir = 'lib/xhyve/vmnet'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Spec test
|
13
|
+
RSpec::Core::RakeTask.new(:spec)
|
14
|
+
|
15
|
+
desc 'Build xhyve binary'
|
16
|
+
task :vendor do
|
17
|
+
Dir.chdir('tmp') do
|
18
|
+
unless Dir.exist?('xhyve/.git')
|
19
|
+
system('git clone https://github.com/mist64/xhyve.git') || fail('Could not clone xhyve')
|
20
|
+
end
|
21
|
+
Dir.chdir('xhyve') do
|
22
|
+
system('git fetch') || fail('Could not fetch')
|
23
|
+
system('git reset --hard origin/master') || fail('Could not reset head')
|
24
|
+
system('make') || fail('Make failed')
|
25
|
+
end
|
26
|
+
end
|
27
|
+
FileUtils.mkdir_p('lib/xhyve/vendor')
|
28
|
+
FileUtils.cp('tmp/xhyve/build/xhyve', 'lib/xhyve/vendor')
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Build the ruby gem'
|
32
|
+
task :build do
|
33
|
+
system('gem build xhyve-ruby.gemspec') || fail('Failed to build gem')
|
34
|
+
end
|
35
|
+
|
36
|
+
desc 'Install gem'
|
37
|
+
task install: :build do
|
38
|
+
system('gem install xhyve-ruby*.gem') || fail('Couldn not install gem')
|
39
|
+
end
|
40
|
+
|
41
|
+
# Deps and defaults
|
42
|
+
task default: :spec
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'xhyve'
|
2
|
+
|
3
|
+
guest = Xhyve::Guest.new(
|
4
|
+
kernel: 'spec/fixtures/guest/vmlinuz', # path to vmlinuz
|
5
|
+
initrd: 'spec/fixtures/guest/initrd', # path to initrd
|
6
|
+
cmdline: 'earlyprintk=true console=ttyS0', # boot flags to linux
|
7
|
+
serial: 'com1', # com1 / com2 (maps to ttyS0, ttyS1, etc)
|
8
|
+
memory: '200M', # amount of memory in M/G
|
9
|
+
processors: 1, # number of processors
|
10
|
+
networking: true, # use sudo? (required for network unless signed)
|
11
|
+
acpi: true, # set up acpi? (required for clean shutdown)
|
12
|
+
)
|
13
|
+
|
14
|
+
pid = guest.start # starting the guest spawns an xhyve subprocess, returning the pid
|
15
|
+
puts pid
|
16
|
+
puts guest.mac # get MAC address of the guest
|
17
|
+
puts guest.ip # get the IP of the guest
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Gem.post_install do
|
2
|
+
if Gem::Platform.local.os =~ /darwin/
|
3
|
+
# Required until https://github.com/mist64/xhyve/issues/60 is resolved
|
4
|
+
bin = File.expand_path('../xhyve/vendor/xhyve', __FILE__)
|
5
|
+
`/usr/bin/osascript -e 'do shell script "chown root #{bin} && chmod +s #{bin}" with administrator privileges'`
|
6
|
+
end
|
7
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Xhyve
|
2
|
+
# Parse DHCP leases file for a MAC address, and get its ip.
|
3
|
+
module DHCP
|
4
|
+
extend self
|
5
|
+
LEASES_FILE = '/var/db/dhcpd_leases'
|
6
|
+
WAIT_TIME = 1
|
7
|
+
MAX_ATTEMPTS = 60
|
8
|
+
|
9
|
+
def get_ip_for_mac(mac)
|
10
|
+
max = ENV.key?('MAX_IP_WAIT') ? ENV['MAX_IP_WAIT'].to_i : nil
|
11
|
+
ip = wait_for(max: max) do
|
12
|
+
ip = parse_lease_file_for_mac(mac)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_lease_file_for_mac(mac)
|
17
|
+
lease_file = (ENV['LEASES_FILE'] || LEASES_FILE)
|
18
|
+
contents = wait_for do
|
19
|
+
File.read(lease_file) if File.exists?(lease_file)
|
20
|
+
end
|
21
|
+
pattern = contents.match(/ip_address=(\S+)\n\thw_address=\d+,#{mac}/)
|
22
|
+
if pattern
|
23
|
+
addrs = pattern.captures
|
24
|
+
addrs.first if addrs
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def wait_for(max: nil)
|
31
|
+
attempts = 0
|
32
|
+
max ||= MAX_ATTEMPTS
|
33
|
+
while attempts < max
|
34
|
+
attempts += 1
|
35
|
+
result = yield
|
36
|
+
return result if result
|
37
|
+
sleep(WAIT_TIME)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require 'io/console'
|
3
|
+
|
4
|
+
require 'xhyve/dhcp'
|
5
|
+
|
6
|
+
module Xhyve
|
7
|
+
BINARY_PATH = File.expand_path('../../../lib/xhyve/vendor/xhyve', __FILE__).freeze
|
8
|
+
|
9
|
+
# An object to represent a guest that we can start and stop
|
10
|
+
# Effectively, it's a command wrapper around xhyve to provide an
|
11
|
+
# object oriented interface to a hypervisor guest
|
12
|
+
class Guest
|
13
|
+
PCI_BASE = 3
|
14
|
+
NULLDEV = '/dev/null'
|
15
|
+
|
16
|
+
attr_reader :pid, :uuid, :mac
|
17
|
+
|
18
|
+
def initialize(**opts)
|
19
|
+
@kernel = opts.fetch(:kernel)
|
20
|
+
@initrd = opts.fetch(:initrd)
|
21
|
+
@cmdline = opts.fetch(:cmdline)
|
22
|
+
@blockdevs = [opts[:blockdevs] || []].flatten
|
23
|
+
@memory = opts[:memory] || '500M'
|
24
|
+
@processors = opts[:processors] || '1'
|
25
|
+
@uuid = opts[:uuid] || SecureRandom.uuid
|
26
|
+
@serial = opts[:serial] || 'com1'
|
27
|
+
@acpi = opts.fetch(:acpi, true)
|
28
|
+
@networking = opts.fetch(:networking, true)
|
29
|
+
@foreground = opts[:foreground] || false
|
30
|
+
@binary = opts[:binary] || BINARY_PATH
|
31
|
+
@command = build_command
|
32
|
+
@mac = find_mac
|
33
|
+
end
|
34
|
+
|
35
|
+
def start
|
36
|
+
outfile, infile = redirection
|
37
|
+
@pid = spawn(@command, [:out, :err] => outfile, in: infile)
|
38
|
+
if @foreground
|
39
|
+
Process.wait(@pid)
|
40
|
+
outfile.cooked!
|
41
|
+
infile.cooked!
|
42
|
+
end
|
43
|
+
@pid
|
44
|
+
end
|
45
|
+
|
46
|
+
def stop
|
47
|
+
Process.kill('KILL', @pid)
|
48
|
+
end
|
49
|
+
|
50
|
+
def running?
|
51
|
+
(true if Process.kill(0, @pid) rescue false)
|
52
|
+
end
|
53
|
+
|
54
|
+
def ip
|
55
|
+
@ip ||= Xhyve::DHCP.get_ip_for_mac(@mac)
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def redirection
|
61
|
+
if @foreground
|
62
|
+
[$stdout.raw!, $stdin.raw! ]
|
63
|
+
else
|
64
|
+
[NULLDEV, NULLDEV]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_mac
|
69
|
+
`#{@command} -M`.strip.gsub(/MAC:\s+/,'')
|
70
|
+
end
|
71
|
+
|
72
|
+
def build_command
|
73
|
+
[
|
74
|
+
"#{@binary}",
|
75
|
+
"#{'-A' if @acpi}",
|
76
|
+
'-U', @uuid,
|
77
|
+
'-m', @memory,
|
78
|
+
'-c', @processors,
|
79
|
+
'-s', '0:0,hostbridge',
|
80
|
+
"#{"-s #{PCI_BASE - 1}:0,virtio-net" if @networking }" ,
|
81
|
+
"#{"#{@blockdevs.each_with_index.map { |p, i| "-s #{PCI_BASE + i},virtio-blk,#{p}" }.join(' ')}" unless @blockdevs.empty? }",
|
82
|
+
'-s', '31,lpc',
|
83
|
+
'-l', "#{@serial},stdio",
|
84
|
+
'-f' "kexec,#{@kernel},#{@initrd},'#{@cmdline}'"
|
85
|
+
].join(' ')
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
Binary file
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{
|
2
|
+
name=box
|
3
|
+
ip_address=192.168.64.34
|
4
|
+
hw_address=1,9a:65:1b:12:cf:32
|
5
|
+
identifier=1,9a:65:1b:12:cf:32
|
6
|
+
lease=0x56551009
|
7
|
+
}
|
8
|
+
{
|
9
|
+
name=localhost
|
10
|
+
ip_address=192.168.64.5
|
11
|
+
hw_address=1,a6:84:b2:34:cf:32
|
12
|
+
identifier=1,a6:84:b2:34:cf:32
|
13
|
+
lease=0x5653f52c
|
14
|
+
}
|
15
|
+
{
|
16
|
+
name=localhost
|
17
|
+
ip_address=192.168.64.4
|
18
|
+
hw_address=1,ea:28:a:33:cf:32
|
19
|
+
identifier=1,ea:28:a:33:cf:32
|
20
|
+
lease=0x5653f4eb
|
21
|
+
}
|
22
|
+
{
|
23
|
+
name=localhost
|
24
|
+
ip_address=192.168.64.3
|
25
|
+
hw_address=1,e2:ff:e:70:cf:32
|
26
|
+
identifier=1,e2:ff:e:70:cf:32
|
27
|
+
lease=0x5653f496
|
28
|
+
}
|
29
|
+
{
|
30
|
+
name=localhost
|
31
|
+
ip_address=192.168.64.2
|
32
|
+
hw_address=1,5a:90:52:13:cf:32
|
33
|
+
identifier=1,5a:90:52:13:cf:32
|
34
|
+
lease=0x5653f3c5
|
35
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#
|
2
|
+
|
3
|
+
We use tinycore linux, with a small persistence volume that just has openssh.
|
4
|
+
|
5
|
+
To regenerate this persistence volume (on osx):
|
6
|
+
|
7
|
+
```
|
8
|
+
# Create a sparse filesystem
|
9
|
+
|
10
|
+
dd if=/dev/zero of=loop.img bs=1 count=0 seek=10m
|
11
|
+
|
12
|
+
# Mount the image in xhyve, (without opt=vda1) then create a partition table and mkfs.ext4 it.
|
13
|
+
# It will likely be /dev/vda
|
14
|
+
# Then reboot with opt=vda
|
15
|
+
# confirm it's mounted over /opt, then make your changes as per
|
16
|
+
# http://myblog-kenton.blogspot.ca/2012/03/install-openssh-server-on-tiny-core.html
|
17
|
+
|
18
|
+
tce-load -iw openssh.tcz
|
19
|
+
sudo cp /usr/local/etc/ssh/sshd_config_example /usr/local/etc/ssh/sshd_config
|
20
|
+
cat >> /opt/.filetool.lst <<EOF
|
21
|
+
/usr/local/etc/ssh
|
22
|
+
/etc/passwd
|
23
|
+
/etc/shadow
|
24
|
+
EOF
|
25
|
+
|
26
|
+
echo "/usr/local/etc/init.d/openssh start" >> /opt/bootlocal.sh
|
27
|
+
|
28
|
+
sudo /usr/local/etc/init.d/openssh start
|
29
|
+
sudo filetool.sh -b
|
30
|
+
|
31
|
+
```
|
32
|
+
|
33
|
+
When booting set user=console boot flag, and it will create the console user with password defaulting to 'tcuser'
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
RSpec.describe Xhyve::DHCP do
|
4
|
+
let(:leases) do
|
5
|
+
{
|
6
|
+
'9a:65:1b:12:cf:32' => '192.168.64.34',
|
7
|
+
'a6:84:b2:34:cf:32' => '192.168.64.5',
|
8
|
+
'ea:28:a:33:cf:32' => '192.168.64.4',
|
9
|
+
'e2:ff:e:70:cf:32' => '192.168.64.3',
|
10
|
+
'5a:90:52:13:cf:32' => '192.168.64.2'
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
before :all do
|
15
|
+
ENV['LEASES_FILE'] = File.join(FIXTURE_PATH, 'dhcpd_leases.txt')
|
16
|
+
ENV['MAX_IP_WAIT'] = '1'
|
17
|
+
end
|
18
|
+
|
19
|
+
after :all do
|
20
|
+
ENV.delete('LEASES_FILE')
|
21
|
+
ENV.delete('MAX_IP_WAIT')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'parses the leases file to get an IP from a MAC' do
|
25
|
+
leases.each do |mac, ip|
|
26
|
+
expect(Xhyve::DHCP.get_ip_for_mac(mac)).to_not be_nil
|
27
|
+
expect(Xhyve::DHCP.get_ip_for_mac(mac)).to eq(ip)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'returns nil if no lease is found' do
|
32
|
+
expect(Xhyve::DHCP.get_ip_for_mac('fakemac')).to be_nil
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
2
|
+
|
3
|
+
RSpec.describe Xhyve::Guest do
|
4
|
+
before :all do
|
5
|
+
kernel = File.join(FIXTURE_PATH, 'guest', 'vmlinuz')
|
6
|
+
initrd = File.join(FIXTURE_PATH, 'guest', 'initrd')
|
7
|
+
blockdev = File.join(FIXTURE_PATH, 'guest', 'loop.img')
|
8
|
+
cmdline = 'earlyprintk=true console=ttyS0 user=console opt=vda tce=vda'
|
9
|
+
uuid = SecureRandom.uuid # '32e54269-d1e2-4bdf-b4ff-bbe0eb42572d' #
|
10
|
+
|
11
|
+
@guest = Xhyve::Guest.new(kernel: kernel, initrd: initrd, cmdline: cmdline, blockdevs: blockdev, uuid: uuid, serial: 'com1')
|
12
|
+
@guest.start
|
13
|
+
end
|
14
|
+
|
15
|
+
after :all do
|
16
|
+
@guest.stop
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'Can start a guest' do
|
20
|
+
expect(@guest.pid).to_not be_nil
|
21
|
+
expect(@guest.pid).to be > 0
|
22
|
+
expect(@guest.running?).to eq(true)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'Can get the MAC of a guest' do
|
26
|
+
expect(@guest.mac).to_not be_nil
|
27
|
+
expect(@guest.mac).to_not be_empty
|
28
|
+
expect(@guest.mac).to match(/\w\w:\w\w:\w\w:\w\w:\w\w:\w\w/)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'Can get the IP of a guest' do
|
32
|
+
expect(@guest.ip).to_not be_nil
|
33
|
+
expect(@guest.ip).to match(/\d+\.+\d+\.\d+\.\d+/)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'Can ping the guest' do
|
37
|
+
expect(ping(@guest.ip)).to eq(true)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'Can ssh to the guest' do
|
41
|
+
expect(on_guest(@guest.ip, 'hostname')).to eq('box')
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Correctly sets processors' do
|
45
|
+
expect(on_guest(@guest.ip, "cat /proc/cpuinfo | grep 'cpu cores' | awk '{print $4}'")).to eq('1')
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'Correctly sets memory' do
|
49
|
+
expect(on_guest(@guest.ip, "free -mm | grep 'Mem:' | awk '{print $2}'").to_i).to be_within(50).of(500)
|
50
|
+
end
|
51
|
+
end unless ENV['TRAVIS']
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
require 'securerandom'
|
5
|
+
require 'net/ssh'
|
6
|
+
require 'net/ping'
|
7
|
+
require File.expand_path('../../lib/xhyve.rb', __FILE__)
|
8
|
+
|
9
|
+
FIXTURE_PATH = File.expand_path('../../spec/fixtures', __FILE__)
|
10
|
+
|
11
|
+
# def self.append_features(mod)
|
12
|
+
# mod.class_eval %[
|
13
|
+
# around(:each) do |example|
|
14
|
+
# example.run
|
15
|
+
# end
|
16
|
+
# ]
|
17
|
+
# end
|
18
|
+
# end
|
19
|
+
|
20
|
+
def ping(ip)
|
21
|
+
attempts = 0
|
22
|
+
max_attempts = 60
|
23
|
+
sleep_time = 1
|
24
|
+
|
25
|
+
while attempts < max_attempts
|
26
|
+
attempts += 1
|
27
|
+
sleep(sleep_time)
|
28
|
+
begin
|
29
|
+
return true if Net::Ping::ICMP.new(ip).ping
|
30
|
+
rescue
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def on_guest(ip, command)
|
36
|
+
output = ''
|
37
|
+
Net::SSH.start(ip, 'console', password: 'tcuser') do |ssh|
|
38
|
+
output = ssh.exec!(command)
|
39
|
+
end
|
40
|
+
output.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
RSpec.configure do |config|
|
44
|
+
config.order = :defined
|
45
|
+
config.expect_with :rspec do |expectations|
|
46
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
47
|
+
end
|
48
|
+
|
49
|
+
config.mock_with :rspec do |mocks|
|
50
|
+
mocks.verify_partial_doubles = true
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'xhyve/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'xhyve-ruby'
|
7
|
+
s.version = Xhyve::VERSION
|
8
|
+
s.date = '2015-11-23'
|
9
|
+
s.summary = 'Ruby wrapper for xhyve'
|
10
|
+
s.description = 'Provides a means of interacting with xhyve from ruby'
|
11
|
+
s.authors = ['Dale Hamel']
|
12
|
+
s.email = 'dale.hamel@srvthe.net'
|
13
|
+
s.files = Dir['lib/**/*']
|
14
|
+
s.homepage =
|
15
|
+
'https://github.com/dalehamel/xhyve-ruby'
|
16
|
+
s.license = 'MIT'
|
17
|
+
s.add_development_dependency 'simplecov', ['=0.10.0']
|
18
|
+
s.add_development_dependency 'rspec', ['=3.2.0']
|
19
|
+
s.add_development_dependency 'net-ssh', ['=3.0.1']
|
20
|
+
s.add_development_dependency 'net-ping', ['=1.7.8']
|
21
|
+
s.add_development_dependency 'rake', ['=10.4.2']
|
22
|
+
s.add_development_dependency 'rake-compiler', ['=0.9.5']
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vagrant-xhyve
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Patrick Armstrong
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xhyve-ruby
|
@@ -129,8 +129,29 @@ files:
|
|
129
129
|
- templates/metadata.json.erb
|
130
130
|
- templates/vagrant-aws_package_Vagrantfile.erb
|
131
131
|
- vagrant-xhyve.gemspec
|
132
|
+
- vendor/xhyve-ruby/example/test.rb
|
133
|
+
- vendor/xhyve-ruby/Gemfile
|
134
|
+
- vendor/xhyve-ruby/lib/rubygems_plugin.rb
|
135
|
+
- vendor/xhyve-ruby/lib/xhyve/dhcp.rb
|
136
|
+
- vendor/xhyve-ruby/lib/xhyve/guest.rb
|
137
|
+
- vendor/xhyve-ruby/lib/xhyve/vendor/xhyve
|
138
|
+
- vendor/xhyve-ruby/lib/xhyve/version.rb
|
139
|
+
- vendor/xhyve-ruby/lib/xhyve.rb
|
140
|
+
- vendor/xhyve-ruby/Rakefile
|
141
|
+
- vendor/xhyve-ruby/README.md
|
142
|
+
- vendor/xhyve-ruby/spec/fixtures/dhcpd_leases.txt
|
143
|
+
- vendor/xhyve-ruby/spec/fixtures/guest/initrd
|
144
|
+
- vendor/xhyve-ruby/spec/fixtures/guest/loop.img
|
145
|
+
- vendor/xhyve-ruby/spec/fixtures/guest/README.md
|
146
|
+
- vendor/xhyve-ruby/spec/fixtures/guest/vmlinuz
|
147
|
+
- vendor/xhyve-ruby/spec/lib/dhcp_spec.rb
|
148
|
+
- vendor/xhyve-ruby/spec/lib/guest_spec.rb
|
149
|
+
- vendor/xhyve-ruby/spec/spec_helper.rb
|
150
|
+
- vendor/xhyve-ruby/xhyve-ruby.gemspec
|
132
151
|
- .gitignore
|
133
152
|
- .rspec
|
153
|
+
- vendor/xhyve-ruby/.gitignore
|
154
|
+
- vendor/xhyve-ruby/.travis.yml
|
134
155
|
homepage: http://github.com/oldpatricka/vagrant-xhyve
|
135
156
|
licenses:
|
136
157
|
- MIT
|