vagrant-haipa 0.0.1
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 +19 -0
- data/.vscode/launch.json +29 -0
- data/Gemfile +20 -0
- data/LICENSE +373 -0
- data/README.md +111 -0
- data/Rakefile +24 -0
- data/box/haipa.box +0 -0
- data/box/metadata.json +3 -0
- data/lib/vagrant-haipa.rb +20 -0
- data/lib/vagrant-haipa/actions.rb +209 -0
- data/lib/vagrant-haipa/actions/check_state.rb +19 -0
- data/lib/vagrant-haipa/actions/connect_haipa.rb +24 -0
- data/lib/vagrant-haipa/actions/create_machine.rb +56 -0
- data/lib/vagrant-haipa/actions/delete_machine.rb +31 -0
- data/lib/vagrant-haipa/actions/is_created.rb +18 -0
- data/lib/vagrant-haipa/actions/is_stopped.rb +18 -0
- data/lib/vagrant-haipa/actions/message_already_created.rb +16 -0
- data/lib/vagrant-haipa/actions/message_not_created.rb +16 -0
- data/lib/vagrant-haipa/actions/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-haipa/actions/modify_provision_path.rb +38 -0
- data/lib/vagrant-haipa/actions/set_name.rb +53 -0
- data/lib/vagrant-haipa/actions/shut_down.rb +33 -0
- data/lib/vagrant-haipa/actions/start_machine.rb +34 -0
- data/lib/vagrant-haipa/actions/stop_machine.rb +33 -0
- data/lib/vagrant-haipa/actions/wait_for_ip_address.rb +32 -0
- data/lib/vagrant-haipa/config.rb +54 -0
- data/lib/vagrant-haipa/errors.rb +41 -0
- data/lib/vagrant-haipa/helpers/client.rb +111 -0
- data/lib/vagrant-haipa/helpers/result.rb +40 -0
- data/lib/vagrant-haipa/plugin.rb +22 -0
- data/lib/vagrant-haipa/provider.rb +118 -0
- data/lib/vagrant-haipa/version.rb +5 -0
- data/locales/en.yml +95 -0
- data/test/Vagrantfile +43 -0
- data/test/cookbooks/test/recipes/default.rb +1 -0
- data/test/scripts/provision.sh +3 -0
- data/test/test.sh +13 -0
- data/test/test_id_rsa +27 -0
- data/test/test_id_rsa.pub +1 -0
- data/vagrant +27 -0
- data/vagrant-haipa.gemspec +21 -0
- metadata +132 -0
data/README.md
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
Haipa Vagrant Provider
|
2
|
+
=================================
|
3
|
+
|
4
|
+
|
5
|
+
`vagrant-haipa` is a Vagrant provider plugin that supports the management of Hyper-V virtual machines with [Haipa](http://www.haipa.io).
|
6
|
+
|
7
|
+
Features include:
|
8
|
+
- Create and destroy Haipa Machines
|
9
|
+
- Power on and off Haipa Machines
|
10
|
+
|
11
|
+
|
12
|
+
Install
|
13
|
+
-------
|
14
|
+
Install the provider plugin using the Vagrant command-line interface:
|
15
|
+
|
16
|
+
`vagrant plugin install vagrant-haipa`
|
17
|
+
|
18
|
+
|
19
|
+
Configure
|
20
|
+
---------
|
21
|
+
Once the provider has been installed, you will need to configure your project to use it. See the following example for a basic `Vagrantfile` implementation:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
config.vm.define :ubuntu do |ubuntu|
|
25
|
+
ubuntu.vm.provider :haipa do |provider|
|
26
|
+
provider.vm_config = {
|
27
|
+
'Memory' => {
|
28
|
+
'Startup' => 2048
|
29
|
+
},
|
30
|
+
'Disks' => [
|
31
|
+
{
|
32
|
+
"Template" => 'c:\hyperv-templates\ubuntu-xenial.vhdx',
|
33
|
+
"Size" => 20
|
34
|
+
}
|
35
|
+
],
|
36
|
+
'NetworkAdapters' => [
|
37
|
+
{
|
38
|
+
"Name" => "eth0",
|
39
|
+
"SwitchName" => "Default Switch",
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
|
49
|
+
**Supported Configuration Attributes**
|
50
|
+
|
51
|
+
The following attributes are available to further configure the provider:
|
52
|
+
- `provider.vm_config`
|
53
|
+
* A Hash with the Haipa vm configuration
|
54
|
+
- `provider.provision`
|
55
|
+
* A Hash with the Haipa provision configuration
|
56
|
+
|
57
|
+
Run
|
58
|
+
---
|
59
|
+
After creating your project's `Vagrantfile` with the required configuration
|
60
|
+
attributes described above, you may create a new Machine with the following
|
61
|
+
command:
|
62
|
+
|
63
|
+
$ vagrant up --provider=haipa
|
64
|
+
|
65
|
+
This command will create a new machine, setup your SSH key for authentication,
|
66
|
+
create a new user account, and run the provisioners you have configured.
|
67
|
+
|
68
|
+
**Supported Commands**
|
69
|
+
|
70
|
+
The provider supports the following Vagrant sub-commands:
|
71
|
+
- `vagrant destroy` - Destroys the machine instance.
|
72
|
+
- `vagrant ssh` - Logs into the machine instance using the configured user account.
|
73
|
+
- `vagrant halt` - Powers off the machine instance.
|
74
|
+
- `vagrant provision` - Runs the configured provisioners and rsyncs any specified `config.vm.synced_folder`.
|
75
|
+
- `vagrant status` - Outputs the status (active, off, not created) for the machine instance.
|
76
|
+
|
77
|
+
|
78
|
+
Troubleshooting
|
79
|
+
---------------
|
80
|
+
Before submitting a GitHub issue, please ensure both Vagrant and vagrant-haipa are fully up-to-date.
|
81
|
+
* For the latest Vagrant version, please visit the [Vagrant](https://www.vagrantup.com/) website
|
82
|
+
* To update Vagrant plugins, run the following command: `vagrant plugin update`
|
83
|
+
|
84
|
+
|
85
|
+
Contribute
|
86
|
+
----------
|
87
|
+
To contribute, fork then clone the repository, and then the following:
|
88
|
+
|
89
|
+
**Developing**
|
90
|
+
|
91
|
+
1. Install [Bundler](http://bundler.io/)
|
92
|
+
2. Currently the Bundler version is locked to 1.7.9, please install this version.
|
93
|
+
* `sudo gem install bundler -v '1.7.9'`
|
94
|
+
3. Then install vagrant-haipa dependencies:
|
95
|
+
* `bundle _1.7.9_ install`
|
96
|
+
4. Do your development and run a few commands, one to get started would be:
|
97
|
+
* `bundle _1.7.9_ exec vagrant haipa-list images`
|
98
|
+
5. You can then run a test:
|
99
|
+
* `bundle _1.7.9_ exec rake test`
|
100
|
+
6. Once you are satisfied with your changes, please submit a pull request.
|
101
|
+
|
102
|
+
**Testing**
|
103
|
+
|
104
|
+
1. Build and package your newly developed code:
|
105
|
+
* `rake gem:build`
|
106
|
+
2. Then install the packaged plugin:
|
107
|
+
* `vagrant plugin install pkg/vagrant-haipa-*.gem`
|
108
|
+
3. Once you're done testing, roll-back to the latest released version:
|
109
|
+
* `vagrant plugin uninstall vagrant-haipa`
|
110
|
+
* `vagrant plugin install vagrant-haipa`
|
111
|
+
4. Once you're satisfied developing and testing your new code, please submit a pull request for review.
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
|
5
|
+
namespace :gem do
|
6
|
+
Bundler::GemHelper.install_tasks
|
7
|
+
end
|
8
|
+
|
9
|
+
task :test do
|
10
|
+
result = sh 'bash test/test.sh'
|
11
|
+
|
12
|
+
if result
|
13
|
+
puts 'Success!'
|
14
|
+
else
|
15
|
+
puts 'Failure!'
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def env
|
21
|
+
['DO_CLIENT_ID', 'DO_API_KEY', 'VAGRANT_LOG'].inject('') do |acc, key|
|
22
|
+
acc += "#{key}=#{ENV[key] || 'error'} "
|
23
|
+
end
|
24
|
+
end
|
data/box/haipa.box
ADDED
Binary file
|
data/box/metadata.json
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'vagrant-haipa/version'
|
2
|
+
require 'vagrant-haipa/plugin'
|
3
|
+
require 'vagrant-haipa/errors'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Haipa
|
7
|
+
def self.source_root
|
8
|
+
@source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.public_key(private_key_path)
|
12
|
+
File.read("#{private_key_path}.pub")
|
13
|
+
rescue
|
14
|
+
raise Errors::PublicKeyError, :path => "#{private_key_path}.pub"
|
15
|
+
end
|
16
|
+
|
17
|
+
I18n.load_path << File.expand_path('locales/en.yml', source_root)
|
18
|
+
I18n.reload!
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Haipa
|
3
|
+
module Actions
|
4
|
+
include Vagrant::Action::Builtin
|
5
|
+
|
6
|
+
# This action is called to halt the remote machine.
|
7
|
+
def self.action_halt
|
8
|
+
Vagrant::Action::Builder.new.tap do |b|
|
9
|
+
b.use ConfigValidate
|
10
|
+
b.use Call, IsCreated do |env, b2|
|
11
|
+
unless env[:result]
|
12
|
+
b2.use MessageNotCreated
|
13
|
+
next
|
14
|
+
end
|
15
|
+
|
16
|
+
b2.use ConnectHaipa
|
17
|
+
b2.use StopMachine
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# This action is called to terminate the remote machine.
|
23
|
+
def self.action_destroy
|
24
|
+
Vagrant::Action::Builder.new.tap do |b|
|
25
|
+
b.use Call, DestroyConfirm do |env, b2|
|
26
|
+
if env[:result]
|
27
|
+
b2.use ConfigValidate
|
28
|
+
b2.use Call, IsCreated do |env2, b3|
|
29
|
+
unless env2[:result]
|
30
|
+
b3.use MessageNotCreated
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
b3.use ConnectHaipa
|
35
|
+
b3.use ProvisionerCleanup, :before if defined?(ProvisionerCleanup)
|
36
|
+
b3.use DeleteMachine
|
37
|
+
end
|
38
|
+
else
|
39
|
+
b2.use MessageWillNotDestroy
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This action is called when `vagrant provision` is called.
|
46
|
+
def self.action_provision
|
47
|
+
Vagrant::Action::Builder.new.tap do |b|
|
48
|
+
b.use ConfigValidate
|
49
|
+
b.use Call, IsCreated do |env, b2|
|
50
|
+
unless env[:result]
|
51
|
+
b2.use MessageNotCreated
|
52
|
+
next
|
53
|
+
end
|
54
|
+
|
55
|
+
b2.use Provision
|
56
|
+
b2.use SyncedFolderCleanup
|
57
|
+
b2.use SyncedFolders
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# This action is called to read the SSH info of the machine. The
|
63
|
+
# resulting state is expected to be put into the `:machine_ssh_info`
|
64
|
+
# key.
|
65
|
+
def self.action_read_ssh_info
|
66
|
+
Vagrant::Action::Builder.new.tap do |b|
|
67
|
+
b.use ConfigValidate
|
68
|
+
b.use ConnectHaipa
|
69
|
+
b.use ReadSSHInfo
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# This action is called to read the state of the machine. The
|
74
|
+
# resulting state is expected to be put into the `:machine_state_id`
|
75
|
+
# key.
|
76
|
+
def self.action_read_state
|
77
|
+
Vagrant::Action::Builder.new.tap do |b|
|
78
|
+
b.use ConfigValidate
|
79
|
+
b.use ConnectHaipa
|
80
|
+
b.use ReadState
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# This action is called to SSH into the machine.
|
85
|
+
def self.action_ssh
|
86
|
+
Vagrant::Action::Builder.new.tap do |b|
|
87
|
+
b.use ConfigValidate
|
88
|
+
b.use Call, IsCreated do |env, b2|
|
89
|
+
unless env[:result]
|
90
|
+
b2.use MessageNotCreated
|
91
|
+
next
|
92
|
+
end
|
93
|
+
|
94
|
+
b2.use SSHExec
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.action_ssh_run
|
100
|
+
Vagrant::Action::Builder.new.tap do |b|
|
101
|
+
b.use ConfigValidate
|
102
|
+
b.use Call, IsCreated do |env, b2|
|
103
|
+
unless env[:result]
|
104
|
+
b2.use MessageNotCreated
|
105
|
+
next
|
106
|
+
end
|
107
|
+
|
108
|
+
b2.use SSHRun
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.action_ssh_ip
|
114
|
+
Vagrant::Action::Builder.new.tap do |b|
|
115
|
+
b.use Call, ConfigValidate do |env, b2|
|
116
|
+
b2.use WaitForIpAddress
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.action_start
|
122
|
+
Vagrant::Action::Builder.new.tap do |b|
|
123
|
+
b.use Call, IsState, :running do |env1, b1|
|
124
|
+
if env1[:result]
|
125
|
+
b1.use action_provision
|
126
|
+
next
|
127
|
+
end
|
128
|
+
|
129
|
+
b1.use Call, IsState, :paused do |env2, b2|
|
130
|
+
if env2[:result]
|
131
|
+
b2.use action_resume
|
132
|
+
next
|
133
|
+
end
|
134
|
+
|
135
|
+
b2.use Provision
|
136
|
+
b2.use StartMachine
|
137
|
+
b2.use WaitForCommunicator, [:running]
|
138
|
+
b2.use SyncedFolderCleanup
|
139
|
+
b2.use SyncedFolders
|
140
|
+
b2.use SetHostname
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# This action is called to bring the box up from nothing.
|
147
|
+
def self.action_up
|
148
|
+
Vagrant::Action::Builder.new.tap do |b|
|
149
|
+
# b.use HandleBox
|
150
|
+
b.use ConfigValidate
|
151
|
+
# b.use BoxCheckOutdated
|
152
|
+
b.use ConnectHaipa
|
153
|
+
b.use Call, IsCreated do |env1, b1|
|
154
|
+
if env1[:result]
|
155
|
+
b1.use Call, IsStopped do |env2, b2|
|
156
|
+
if env2[:result]
|
157
|
+
b2.use action_start
|
158
|
+
else
|
159
|
+
b2.use MessageAlreadyCreated
|
160
|
+
end
|
161
|
+
end
|
162
|
+
else
|
163
|
+
b1.use SetName
|
164
|
+
b1.use CreateMachine
|
165
|
+
b1.use action_start
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.action_reload
|
172
|
+
Vagrant::Action::Builder.new.tap do |b|
|
173
|
+
b.use ConfigValidate
|
174
|
+
b.use ConnectHaipa
|
175
|
+
b.use Call, IsCreated do |env, b2|
|
176
|
+
unless env[:result]
|
177
|
+
b2.use MessageNotCreated
|
178
|
+
next
|
179
|
+
end
|
180
|
+
|
181
|
+
b2.use action_halt
|
182
|
+
b2.use Call, WaitForState, :stopped, 120 do |env2, b3|
|
183
|
+
if env2[:result]
|
184
|
+
b3.use action_up
|
185
|
+
else
|
186
|
+
# TODO we couldn't reach :stopped, what now?
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# The autoload farm
|
194
|
+
action_root = Pathname.new(File.expand_path('../actions', __FILE__))
|
195
|
+
autoload :ConnectHaipa, action_root.join('connect_haipa')
|
196
|
+
autoload :IsCreated, action_root.join('is_created')
|
197
|
+
autoload :IsStopped, action_root.join('is_stopped')
|
198
|
+
autoload :MessageAlreadyCreated, action_root.join('message_already_created')
|
199
|
+
autoload :MessageNotCreated, action_root.join('message_not_created')
|
200
|
+
autoload :MessageWillNotDestroy, action_root.join('message_will_not_destroy')
|
201
|
+
autoload :CreateMachine, action_root.join('create_machine')
|
202
|
+
autoload :DeleteMachine, action_root.join('delete_machine')
|
203
|
+
autoload :StartMachine, action_root.join('start_machine')
|
204
|
+
autoload :StopMachine, action_root.join('stop_machine')
|
205
|
+
autoload :WaitForIpAddress, action_root.join('wait_for_ip_address')
|
206
|
+
autoload :SetName, action_root.join('set_name')
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Haipa
|
3
|
+
module Actions
|
4
|
+
class CheckState
|
5
|
+
def initialize(app, env)
|
6
|
+
@app = app
|
7
|
+
@machine = env[:machine]
|
8
|
+
@logger = Log4r::Logger.new('vagrant::haipa::check_state')
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(env)
|
12
|
+
env[:machine_state] = @machine.state.id
|
13
|
+
@logger.info "Machine state is '#{@machine.state.id}'"
|
14
|
+
@app.call(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'vagrant-haipa'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Haipa
|
5
|
+
module Actions
|
6
|
+
class ConnectHaipa
|
7
|
+
include Helpers::Client
|
8
|
+
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@machine = env[:machine]
|
12
|
+
@client = client
|
13
|
+
@logger = Log4r::Logger.new('vagrant::haipa::ConnectHaipa')
|
14
|
+
end
|
15
|
+
|
16
|
+
def call(env)
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'vagrant-haipa/helpers/client'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Haipa
|
5
|
+
module Actions
|
6
|
+
class CreateMachine
|
7
|
+
include Helpers::Client
|
8
|
+
include Vagrant::Util::Retryable
|
9
|
+
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@machine = env[:machine]
|
13
|
+
@client = client
|
14
|
+
@logger = Log4r::Logger.new('vagrant::haipa::create_machine')
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
ssh_key_id = [env[:ssh_key_id]]
|
19
|
+
|
20
|
+
# submit new machine request
|
21
|
+
result = @client.post('/odata/Machines', {
|
22
|
+
|
23
|
+
'Name' => env[:generated_name],
|
24
|
+
'VM' => @machine.provider_config.vm_config,
|
25
|
+
"Provisioning" => @machine.provider_config.provision
|
26
|
+
})
|
27
|
+
|
28
|
+
# wait for request to complete
|
29
|
+
env[:ui].info I18n.t('vagrant_haipa.info.creating')
|
30
|
+
@client.wait_for_event(env, result['Id'])
|
31
|
+
|
32
|
+
# assign the machine id for reference in other commands
|
33
|
+
operation_result = @client.request("odata/Operations(#{result['Id']})")
|
34
|
+
@machine.id = operation_result['MachineGuid'].to_s
|
35
|
+
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Both the recover and terminate are stolen almost verbatim from
|
40
|
+
# the Vagrant AWS provider up action
|
41
|
+
def recover(env)
|
42
|
+
return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
|
43
|
+
terminate(env) if @machine.state.id != :not_created
|
44
|
+
end
|
45
|
+
|
46
|
+
def terminate(env)
|
47
|
+
destroy_env = env.dup
|
48
|
+
destroy_env.delete(:interrupted)
|
49
|
+
destroy_env[:config_validate] = false
|
50
|
+
destroy_env[:force_confirm_destroy] = true
|
51
|
+
env[:action_runner].run(Actions.action_destroy, destroy_env)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|