vagrant-xhyve 0.1.0.pre
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 +7 -0
- data/.gitignore +22 -0
- data/.rspec +1 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +13 -0
- data/LICENSE +9 -0
- data/README.md +140 -0
- data/Rakefile +22 -0
- data/example_box/README.md +31 -0
- data/example_box/initrd.gz +0 -0
- data/example_box/metadata.json +3 -0
- data/example_box/vmlinuz +0 -0
- data/lib/vagrant-xhyve/action/boot.rb +142 -0
- data/lib/vagrant-xhyve/action/import.rb +59 -0
- data/lib/vagrant-xhyve/action/is_created.rb +18 -0
- data/lib/vagrant-xhyve/action/is_stopped.rb +18 -0
- data/lib/vagrant-xhyve/action/message_already_created.rb +16 -0
- data/lib/vagrant-xhyve/action/message_not_created.rb +16 -0
- data/lib/vagrant-xhyve/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-xhyve/action/read_ssh_info.rb +33 -0
- data/lib/vagrant-xhyve/action/read_state.rb +43 -0
- data/lib/vagrant-xhyve/action/stop_instance.rb +45 -0
- data/lib/vagrant-xhyve/action/terminate_instance.rb +47 -0
- data/lib/vagrant-xhyve/action/timed_provision.rb +21 -0
- data/lib/vagrant-xhyve/action/wait_for_state.rb +41 -0
- data/lib/vagrant-xhyve/action.rb +193 -0
- data/lib/vagrant-xhyve/config.rb +66 -0
- data/lib/vagrant-xhyve/errors.rb +19 -0
- data/lib/vagrant-xhyve/plugin.rb +73 -0
- data/lib/vagrant-xhyve/provider.rb +50 -0
- data/lib/vagrant-xhyve/util/timer.rb +17 -0
- data/lib/vagrant-xhyve/util/vagrant-xhyve.rb +50 -0
- data/lib/vagrant-xhyve/version.rb +5 -0
- data/lib/vagrant-xhyve.rb +18 -0
- data/locales/en.yml +83 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/vagrant-xhyve/config_spec.rb +33 -0
- data/templates/metadata.json.erb +3 -0
- data/templates/vagrant-aws_package_Vagrantfile.erb +5 -0
- data/vagrant-xhyve.gemspec +60 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: e86cc52b4ca725cdda0aef517879001aa4e3840e
|
4
|
+
data.tar.gz: d61ffc7960f9d079c37ffef1f0f90200f45f922b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 160141682ee37beed607aef94bf476e31d8af4c42742090b3755e381ecb14ecb840bd3646455327a53af6ceca7c7da42e5757a07501e97b464757172250496ec
|
7
|
+
data.tar.gz: b026f9a63b2483c747c4413ddf051f81ca32029d9edf9fe60959923fb6c1b2beeb9a51f889831d93467ee0cd1549fbcbee4927e4884659d8f717847a338a5279
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# OS-specific
|
2
|
+
.DS_Store
|
3
|
+
|
4
|
+
# editors
|
5
|
+
*.swp
|
6
|
+
|
7
|
+
# Bundler/Rubygems
|
8
|
+
*.gem
|
9
|
+
.bundle
|
10
|
+
pkg/*
|
11
|
+
tags
|
12
|
+
Gemfile.lock
|
13
|
+
|
14
|
+
# Vagrant
|
15
|
+
.vagrant
|
16
|
+
Vagrantfile
|
17
|
+
example_box
|
18
|
+
example.box
|
19
|
+
|
20
|
+
# RVM files for gemset/ruby setting
|
21
|
+
.ruby-*
|
22
|
+
.rvmrc
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--format doc --order random --color --fail-fast
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
group :plugins do
|
4
|
+
gemspec
|
5
|
+
end
|
6
|
+
|
7
|
+
group :development do
|
8
|
+
# We depend on Vagrant for development, but we don't add it as a
|
9
|
+
# gem dependency because we expect to be installed within the
|
10
|
+
# Vagrant environment itself using `vagrant plugin`.
|
11
|
+
gem "vagrant", :git => "https://github.com/mitchellh/vagrant.git"
|
12
|
+
end
|
13
|
+
|
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
Copyright (c) 2016 Patrick Armstrong
|
3
|
+
Copyright (c) 2014 Mitchell Hashimoto
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# Vagrant xhyve Provider
|
2
|
+
|
3
|
+
This is a [Vagrant](http://www.vagrantup.com) plugin that adds an [xhyve](http://aws.amazon.com)
|
4
|
+
provider to Vagrant.
|
5
|
+
|
6
|
+
## Features
|
7
|
+
|
8
|
+
* Sorta works
|
9
|
+
|
10
|
+
## Limitations
|
11
|
+
|
12
|
+
You need to use sudo for most vagrant actions with the xhyve driver,
|
13
|
+
due to the entitlements needed for xhyve to run without sudo. More details
|
14
|
+
in the [xhyve github issue](https://github.com/mist64/xhyve/issues/60).
|
15
|
+
|
16
|
+
Also, sometimes launching a VM just fails. But I'm not quite sure why.
|
17
|
+
|
18
|
+
## Usage
|
19
|
+
|
20
|
+
Install using standard Vagrant plugin installation methods. After
|
21
|
+
installing, `vagrant up` and specify the `xhyve` provider. An example is
|
22
|
+
shown below.
|
23
|
+
|
24
|
+
```
|
25
|
+
$ vagrant plugin install vagrant-xhyve
|
26
|
+
...
|
27
|
+
$ sudo vagrant up --provider=xhyve
|
28
|
+
...
|
29
|
+
```
|
30
|
+
|
31
|
+
Of course prior to doing this, you'll need to obtain an XHYVE-compatible
|
32
|
+
box file for Vagrant.
|
33
|
+
|
34
|
+
## Quick Start
|
35
|
+
|
36
|
+
After installing the plugin (instructions above), the quickest way to get
|
37
|
+
started is to actually use a dummy AWS box and specify all the details
|
38
|
+
manually within a `config.vm.provider` block. So first, add the dummy
|
39
|
+
box using any name you want:
|
40
|
+
|
41
|
+
```
|
42
|
+
$ vagrant box add oldpatricka/tinycorelinux
|
43
|
+
...
|
44
|
+
```
|
45
|
+
|
46
|
+
And then make a Vagrantfile that looks like the following, filling in
|
47
|
+
your information where necessary.
|
48
|
+
|
49
|
+
```
|
50
|
+
Vagrant.configure("2") do |config|
|
51
|
+
config.vm.box = "oldpatricka/tinycorelinux"
|
52
|
+
|
53
|
+
config.vm.provider :xhyve do |xhyve|
|
54
|
+
xhyve.cpus = 1
|
55
|
+
xhyve.memory = 1G
|
56
|
+
end
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
And then run `sudo vagrant up --provider=xhyve`.
|
61
|
+
|
62
|
+
This will start a Tiny Core Linux instance.
|
63
|
+
|
64
|
+
## Box Format
|
65
|
+
|
66
|
+
The vagrant-xhyve box format is pretty straightforward. See
|
67
|
+
the [example_box/ directory](https://github.com/oldpatricka/vagrant-xhyve/tree/master/example_box).
|
68
|
+
That directory also contains instructions on how to build a box.
|
69
|
+
|
70
|
+
## Configuration
|
71
|
+
|
72
|
+
This provider exposes quite a few provider-specific configuration options:
|
73
|
+
|
74
|
+
* `memory` - The amount of memory to give the VM. This can just be a simple
|
75
|
+
integer for memory in MB or you can use the suffixed style, eg. 2G for two
|
76
|
+
Gigabytes
|
77
|
+
* `cpus` - The number of CPUs to give the VM
|
78
|
+
|
79
|
+
These can be set like typical provider-specific configuration:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Vagrant.configure("2") do |config|
|
83
|
+
# ... other stuff
|
84
|
+
|
85
|
+
config.vm.provider :xhyve do |xhyve|
|
86
|
+
xhyve.cpus = 2
|
87
|
+
xhyve.memory = 1G
|
88
|
+
end
|
89
|
+
end
|
90
|
+
```
|
91
|
+
## Synced Folders
|
92
|
+
|
93
|
+
There is minimal support for synced folders. Upon `vagrant up`,
|
94
|
+
`vagrant reload`, and `vagrant provision`, the XHYVE provider will use
|
95
|
+
`rsync` (if available) to uni-directionally sync the folder to
|
96
|
+
the remote machine over SSH.
|
97
|
+
|
98
|
+
## Questions
|
99
|
+
|
100
|
+
Q. Should I use this for my work?
|
101
|
+
|
102
|
+
A. Do you want to keep your job? I'm not even sure you should use this for toy
|
103
|
+
projects.
|
104
|
+
|
105
|
+
Q. Why?
|
106
|
+
|
107
|
+
A. This project is powered by ignorance and good intentions.
|
108
|
+
|
109
|
+
Q. Will I even not have to use sudo?
|
110
|
+
|
111
|
+
A. There's a theory in that issue linked above that wrapping xhyve in an
|
112
|
+
app store app would help. If that were the case, you could probably use the
|
113
|
+
embedded binary with vagrant-xhyve.
|
114
|
+
|
115
|
+
## Development
|
116
|
+
|
117
|
+
To work on the `vagrant-xhyve` plugin, clone this repository out, and use
|
118
|
+
[Bundler](http://gembundler.com) to get the dependencies:
|
119
|
+
|
120
|
+
```
|
121
|
+
$ bundle
|
122
|
+
```
|
123
|
+
|
124
|
+
Once you have the dependencies, verify the unit tests pass with `rake`:
|
125
|
+
|
126
|
+
```
|
127
|
+
$ bundle exec rake
|
128
|
+
```
|
129
|
+
|
130
|
+
If those pass, you're ready to start developing the plugin. You can test
|
131
|
+
the plugin without installing it into your Vagrant environment by just
|
132
|
+
creating a `Vagrantfile` in the top level of this directory (it is gitignored)
|
133
|
+
and add the following line to your `Vagrantfile`
|
134
|
+
```ruby
|
135
|
+
Vagrant.require_plugin "vagrant-xhyve"
|
136
|
+
```
|
137
|
+
Use bundler to execute Vagrant:
|
138
|
+
```
|
139
|
+
$ bundle exec vagrant up --provider=xhyve
|
140
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
# Immediately sync all stdout so that tools like buildbot can
|
6
|
+
# immediately load in the output.
|
7
|
+
$stdout.sync = true
|
8
|
+
$stderr.sync = true
|
9
|
+
|
10
|
+
# Change to the directory of this file.
|
11
|
+
Dir.chdir(File.expand_path("../", __FILE__))
|
12
|
+
|
13
|
+
# This installs the tasks that help with gem creation and
|
14
|
+
# publishing.
|
15
|
+
Bundler::GemHelper.install_tasks
|
16
|
+
|
17
|
+
# Install the `spec` task so that we can run tests.
|
18
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
19
|
+
t.rspec_opts = "--order defined"
|
20
|
+
end
|
21
|
+
# Default task is to run the unit tests
|
22
|
+
task :default => :spec
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# vagrant-xhyve Box Format
|
2
|
+
|
3
|
+
A vagrant-xhyve box, like all vagrant boxes is an archive of a directory of
|
4
|
+
files with a metadata file, a kernel, ramdisk, and optionally some raw disk
|
5
|
+
images.
|
6
|
+
|
7
|
+
Here's an example:
|
8
|
+
|
9
|
+
```
|
10
|
+
.
|
11
|
+
|-- block0.img
|
12
|
+
|-- initrd.gz
|
13
|
+
|-- metadata.json
|
14
|
+
`-- vmlinuz
|
15
|
+
```
|
16
|
+
|
17
|
+
The metadata.json just contains the defaults from the vagrant box documentation,
|
18
|
+
that is it looks like:
|
19
|
+
|
20
|
+
```
|
21
|
+
{
|
22
|
+
"provider": "xhyve"
|
23
|
+
}
|
24
|
+
```
|
25
|
+
|
26
|
+
initrd.gz and vmlinuz are extracted from a raw disk image using the technique
|
27
|
+
described in Michael Steil's nice blog post
|
28
|
+
[introducing xhyve](http://www.pagetable.com/?p=831).
|
29
|
+
|
30
|
+
You can have up to ten block devices to attach to your vm, named from block0.img
|
31
|
+
upto block9.img. You can also have zero. That's ok.
|
Binary file
|
data/example_box/vmlinuz
ADDED
Binary file
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require 'json'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require 'vagrant/util/retryable'
|
6
|
+
|
7
|
+
require 'vagrant-xhyve/util/timer'
|
8
|
+
require 'vagrant-xhyve/util/vagrant-xhyve'
|
9
|
+
|
10
|
+
module VagrantPlugins
|
11
|
+
module XHYVE
|
12
|
+
module Action
|
13
|
+
# This runs the configured instance.
|
14
|
+
class Boot
|
15
|
+
include Vagrant::Util::Retryable
|
16
|
+
|
17
|
+
def initialize(app, env)
|
18
|
+
@app = app
|
19
|
+
@logger = Log4r::Logger.new("vagrant_xhyve::action::run_instance")
|
20
|
+
end
|
21
|
+
|
22
|
+
def call(env)
|
23
|
+
# Initialize metrics if they haven't been
|
24
|
+
env[:metrics] ||= {}
|
25
|
+
|
26
|
+
env[:ui].info(" About to launch vm")
|
27
|
+
|
28
|
+
memory = env[:machine].provider_config.memory
|
29
|
+
cpus = env[:machine].provider_config.cpus
|
30
|
+
|
31
|
+
# Launch!
|
32
|
+
env[:ui].info(" -- CPUs: #{cpus}") if cpus
|
33
|
+
env[:ui].info(" -- Memory: #{memory}")
|
34
|
+
|
35
|
+
machine_info_path = File.join(env[:machine].data_dir, "xhyve.json")
|
36
|
+
if File.exist?(machine_info_path) then
|
37
|
+
machine_json = File.read(machine_info_path)
|
38
|
+
machine_options = JSON.parse(machine_json, :symbolize_names => true)
|
39
|
+
machine_uuid = machine_options[:uuid]
|
40
|
+
@logger.debug("Found existing UUID: #{machine_uuid}")
|
41
|
+
else
|
42
|
+
machine_uuid = SecureRandom.uuid
|
43
|
+
@logger.debug("Created new UUID: #{machine_uuid}")
|
44
|
+
end
|
45
|
+
|
46
|
+
image_dir = File.join(env[:machine].data_dir, "image")
|
47
|
+
vmlinuz_file = File.join(image_dir, "vmlinuz")
|
48
|
+
initrd_file = File.join(image_dir, "initrd.gz")
|
49
|
+
block_devices = []
|
50
|
+
|
51
|
+
0.upto(10).each do |blockidx|
|
52
|
+
block_file = File.join(image_dir, "block#{blockidx}.img")
|
53
|
+
if (File.exist? block_file) then
|
54
|
+
@logger.debug("Found block device #{block_file}")
|
55
|
+
block_devices.push(block_file)
|
56
|
+
else
|
57
|
+
break
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
if block_devices.any? then
|
62
|
+
disk_kernel_parameters = "root=/dev/vda1 ro"
|
63
|
+
else
|
64
|
+
disk_kernel_parameters = ""
|
65
|
+
end
|
66
|
+
|
67
|
+
kernel_parameters = "\"earlyprintk=serial console=ttyS0 #{disk_kernel_parameters}\""
|
68
|
+
|
69
|
+
firmware = "kexec,#{vmlinuz_file},#{initrd_file},#{kernel_parameters}"
|
70
|
+
|
71
|
+
@logger.debug("Machine data_dir: #{env[:machine].data_dir}")
|
72
|
+
@logger.debug("Kernel Options: #{kernel_parameters}")
|
73
|
+
@logger.debug("Block Devices: #{block_devices}")
|
74
|
+
|
75
|
+
xhyve_guest = Util::XhyveGuest.new(
|
76
|
+
kernel: vmlinuz_file,
|
77
|
+
initrd: initrd_file,
|
78
|
+
cmdline: kernel_parameters,
|
79
|
+
blockdevs: block_devices,
|
80
|
+
serial: 'com1',
|
81
|
+
memory: memory,
|
82
|
+
processors: cpus,
|
83
|
+
networking: true,
|
84
|
+
acpi: true
|
85
|
+
)
|
86
|
+
|
87
|
+
|
88
|
+
xhyve_pid = xhyve_guest.start
|
89
|
+
env[:ui].info(xhyve_guest.options().to_json)
|
90
|
+
|
91
|
+
# Immediately save the ID since it is created at this point.
|
92
|
+
env[:machine].id = xhyve_pid
|
93
|
+
|
94
|
+
# wait for ip
|
95
|
+
network_ready_retries = 0
|
96
|
+
network_ready_retries_max = 5
|
97
|
+
while true
|
98
|
+
break if env[:interrupted]
|
99
|
+
|
100
|
+
if xhyve_guest.ip
|
101
|
+
break
|
102
|
+
end
|
103
|
+
if network_ready_retries < network_ready_retries_max then
|
104
|
+
network_ready_retries += 1
|
105
|
+
env[:ui].info("Waiting for IP to be ready...")
|
106
|
+
else
|
107
|
+
raise 'Waited too long for IP to be ready. Your VM probably did not boot.'
|
108
|
+
end
|
109
|
+
sleep 2
|
110
|
+
end
|
111
|
+
|
112
|
+
machine_info_path = File.join(env[:machine].data_dir, "xhyve.json")
|
113
|
+
File.write(machine_info_path, xhyve_guest.options().to_json)
|
114
|
+
|
115
|
+
@logger.info(" Launched xhyve VM with PID #{xhyve_pid}, MAC: #{xhyve_guest.mac}, and IP #{xhyve_guest.ip}")
|
116
|
+
|
117
|
+
# Terminate the instance if we were interrupted
|
118
|
+
terminate(env) if env[:interrupted]
|
119
|
+
|
120
|
+
@app.call(env)
|
121
|
+
end
|
122
|
+
|
123
|
+
def recover(env)
|
124
|
+
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
125
|
+
|
126
|
+
if env[:machine].provider.state.id != :not_created
|
127
|
+
# Undo the import
|
128
|
+
terminate(env)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def terminate(env)
|
133
|
+
destroy_env = env.dup
|
134
|
+
destroy_env.delete(:interrupted)
|
135
|
+
destroy_env[:config_validate] = false
|
136
|
+
destroy_env[:force_confirm_destroy] = true
|
137
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "json"
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module XHYVE
|
7
|
+
module Action
|
8
|
+
# This terminates the running instance.
|
9
|
+
class Import
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_xhyve::action::import")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
|
17
|
+
#TODO: Progress bar
|
18
|
+
env[:ui].info("Importing box...")
|
19
|
+
# something like:
|
20
|
+
# # tempfile is a File instance
|
21
|
+
# File.open( new_file, 'wb' ) do |f|
|
22
|
+
# # Read in small 65k chunks to limit memory usage
|
23
|
+
# f.write(tempfile.read(2**16)) until tempfile.eof?
|
24
|
+
# end
|
25
|
+
|
26
|
+
image_dir = File.join(env[:machine].data_dir, "image")
|
27
|
+
box_dir = env[:machine].box.directory
|
28
|
+
|
29
|
+
box_files = [File.join(box_dir, "vmlinuz"), File.join(box_dir, "initrd.gz")]
|
30
|
+
|
31
|
+
0.upto(10).each do |blockidx|
|
32
|
+
block_file = File.join(box_dir, "block#{blockidx}.img")
|
33
|
+
if (File.exist? block_file) then
|
34
|
+
box_files.push(block_file)
|
35
|
+
else
|
36
|
+
break
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
FileUtils.mkdir_p(image_dir)
|
41
|
+
FileUtils.cp(box_files, image_dir)
|
42
|
+
|
43
|
+
env[:ui].info("Done importing box.")
|
44
|
+
|
45
|
+
@app.call(env)
|
46
|
+
end
|
47
|
+
|
48
|
+
def process_alive(pid)
|
49
|
+
begin
|
50
|
+
Process.getpgid(pid)
|
51
|
+
true
|
52
|
+
rescue Errno::ESRCH
|
53
|
+
false
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module XHYVE
|
3
|
+
module Action
|
4
|
+
# This can be used with "Call" built-in to check if the machine
|
5
|
+
# is created and branch in the middleware.
|
6
|
+
class IsCreated
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:result] = env[:machine].id != nil
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module XHYVE
|
3
|
+
module Action
|
4
|
+
# This can be used with "Call" built-in to check if the machine
|
5
|
+
# is stopped and branch in the middleware.
|
6
|
+
class IsStopped
|
7
|
+
def initialize(app, env)
|
8
|
+
@app = app
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:result] = env[:machine].state.id == :stopped
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module XHYVE
|
3
|
+
module Action
|
4
|
+
class MessageAlreadyCreated
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t("vagrant_xhyve.already_status", :status => "created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module XHYVE
|
3
|
+
module Action
|
4
|
+
class MessageNotCreated
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t("vagrant_xhyve.not_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module XHYVE
|
3
|
+
module Action
|
4
|
+
class MessageWillNotDestroy
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(env)
|
10
|
+
env[:ui].info(I18n.t("vagrant_xhyve.will_not_destroy", name: env[:machine].name))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require 'vagrant-xhyve/util/vagrant-xhyve'
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module XHYVE
|
6
|
+
module Action
|
7
|
+
# This action reads the SSH info for the machine and puts it into the
|
8
|
+
# `:machine_ssh_info` key in the environment.
|
9
|
+
class ReadSSHInfo
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_xhyve::action::read_ssh_info")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
env[:machine_ssh_info] = read_ssh_info(env)
|
17
|
+
|
18
|
+
@app.call(env)
|
19
|
+
end
|
20
|
+
|
21
|
+
def read_ssh_info(env)
|
22
|
+
return nil if env[:machine].id.nil?
|
23
|
+
|
24
|
+
machine_info_path = File.join(env[:machine].data_dir, "xhyve.json")
|
25
|
+
machine_json = File.read(machine_info_path)
|
26
|
+
machine_options = JSON.parse(machine_json, :symbolize_names => true)
|
27
|
+
|
28
|
+
return { :host => machine_options[:ip], :port => 22 }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module XHYVE
|
5
|
+
module Action
|
6
|
+
# This action reads the state of the machine and puts it in the
|
7
|
+
# `:machine_state_id` key in the environment.
|
8
|
+
class ReadState
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new("vagrant_xhyve::action::read_state")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
env[:machine_state_id] = read_state(env[:machine])
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_state(machine)
|
21
|
+
return :not_created if machine.id.nil?
|
22
|
+
|
23
|
+
xhyve_pid = Integer(machine.id)
|
24
|
+
|
25
|
+
if process_alive(xhyve_pid) then
|
26
|
+
return :running
|
27
|
+
else
|
28
|
+
return :stopped
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def process_alive(pid)
|
33
|
+
begin
|
34
|
+
Process.getpgid(pid)
|
35
|
+
true
|
36
|
+
rescue Errno::ESRCH
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module XHYVE
|
5
|
+
module Action
|
6
|
+
# This stops the running instance.
|
7
|
+
class StopInstance
|
8
|
+
def initialize(app, env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new("vagrant_xhyve::action::stop_instance")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
if env[:machine].state.id == :stopped
|
15
|
+
env[:ui].info(I18n.t("vagrant_xhyve.already_status", :status => env[:machine].state.id))
|
16
|
+
else
|
17
|
+
env[:ui].info(I18n.t("vagrant_xhyve.stopping"))
|
18
|
+
|
19
|
+
xhyve_pid = env[:machine].id
|
20
|
+
|
21
|
+
if xhyve_pid == nil then
|
22
|
+
@logger.debug("xhyve already gone")
|
23
|
+
elsif process_alive(Integer(xhyve_pid)) then
|
24
|
+
env[:ui].info(" Terminating xhyve instance with PID #{xhyve_pid}")
|
25
|
+
Process.kill(3, Integer(xhyve_pid))
|
26
|
+
else
|
27
|
+
@logger.debug("xhyve PID already gone #{xhyve_pid}")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
@app.call(env)
|
32
|
+
end
|
33
|
+
|
34
|
+
def process_alive(pid)
|
35
|
+
begin
|
36
|
+
Process.getpgid(pid)
|
37
|
+
true
|
38
|
+
rescue Errno::ESRCH
|
39
|
+
false
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|