vagrant-smartos 0.0.1alpha
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.
- data/.gitignore +17 -0
- data/Gemfile +12 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/Vagrantfile +46 -0
- data/example_box/Vagrantfile +0 -0
- data/example_box/metadata.json +3 -0
- data/example_box/smartos.box +0 -0
- data/lib/vagrant-smartos/action/connect_hypervisor.rb +77 -0
- data/lib/vagrant-smartos/action/is_created.rb +24 -0
- data/lib/vagrant-smartos/action/message_already_created.rb +16 -0
- data/lib/vagrant-smartos/action/message_not_created.rb +16 -0
- data/lib/vagrant-smartos/action/read_state.rb +46 -0
- data/lib/vagrant-smartos/action/run_instance.rb +102 -0
- data/lib/vagrant-smartos/action/sync_folders.rb +67 -0
- data/lib/vagrant-smartos/action/terminate_instance.rb +29 -0
- data/lib/vagrant-smartos/config.rb +58 -0
- data/lib/vagrant-smartos/plugin.rb +74 -0
- data/lib/vagrant-smartos/provider.rb +158 -0
- data/lib/vagrant-smartos/version.rb +5 -0
- data/lib/vagrant-smartos.rb +20 -0
- data/locales/en.yml +38 -0
- data/vagrant-smartos.gemspec +21 -0
- metadata +99 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in vagrant-smartos.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :development do
|
7
|
+
## Cargo-culted from vagrant-aws ##
|
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 => "git://github.com/mitchellh/vagrant.git"
|
12
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Thomas Haggett
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Vagrant::Smartos
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'vagrant-smartos'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install vagrant-smartos
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/Vagrantfile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
Vagrant.require_plugin "vagrant-smartos"
|
2
|
+
|
3
|
+
Vagrant.configure("2") do |config|
|
4
|
+
config.vm.box = "smartos-dummy"
|
5
|
+
|
6
|
+
|
7
|
+
config.vm.provision :shell, :inline => "pkgin -y install ruby193-base"
|
8
|
+
|
9
|
+
config.vm.provider :smartos do |smartos, override|
|
10
|
+
|
11
|
+
smartos.hypervisor = "root@172.16.251.129"
|
12
|
+
smartos.image_uuid = "cf7e2f40-9276-11e2-af9a-0bad2233fb0b"
|
13
|
+
|
14
|
+
smartos.ip_address = "172.16.251.18"
|
15
|
+
smartos.subnet_mask = "255.255.255.0"
|
16
|
+
smartos.gateway = "172.16.251.2"
|
17
|
+
end
|
18
|
+
|
19
|
+
config.vm.synced_folder "locales/", "/vagrant"
|
20
|
+
|
21
|
+
|
22
|
+
config.vm.define :test1 do |test|
|
23
|
+
test.vm.provider :smartos do |smartos, override|
|
24
|
+
smartos.ip_address = "172.16.251.21"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
config.vm.define :test2 do |test|
|
29
|
+
test.vm.provider :smartos do |smartos, override|
|
30
|
+
smartos.ip_address = "172.16.251.22"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
config.vm.define :test3 do |test|
|
35
|
+
test.vm.provider :smartos do |smartos, override|
|
36
|
+
smartos.ip_address = "172.16.251.23"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
config.vm.define :test4 do |test|
|
41
|
+
test.vm.provider :smartos do |smartos, override|
|
42
|
+
smartos.ip_address = "172.16.251.24"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
File without changes
|
Binary file
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'net/ssh'
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
|
5
|
+
module Smartos
|
6
|
+
class Provider
|
7
|
+
|
8
|
+
|
9
|
+
class SshWrapper
|
10
|
+
def initialize(net_ssh)
|
11
|
+
@ssh = net_ssh
|
12
|
+
end
|
13
|
+
|
14
|
+
UnexpectedExitCode = Class.new(RuntimeError)
|
15
|
+
CommandExecutionFailed = Class.new(RuntimeError)
|
16
|
+
|
17
|
+
# Public: Execute and block on a command on the remote SSH server
|
18
|
+
#
|
19
|
+
# Returns the stdout data, stderr is piped out to screen
|
20
|
+
#
|
21
|
+
# Raises SshWrapper::UnexpectedExitCode if the exitcode is non-0
|
22
|
+
# Raises SshWrapper::CommandExecutionFailed if the command failed to execute
|
23
|
+
def exec(command)
|
24
|
+
stdout_data = []
|
25
|
+
channel = @ssh.open_channel do |ch|
|
26
|
+
ch.exec command do |ch, success|
|
27
|
+
raise SshWrapper::CommandExecutionFailed unless success
|
28
|
+
|
29
|
+
# "on_data" is called when the process writes something to stdout
|
30
|
+
ch.on_data do |c, data|
|
31
|
+
stdout_data << data
|
32
|
+
end
|
33
|
+
|
34
|
+
# "on_extended_data" is called when the process writes something to stderr
|
35
|
+
ch.on_extended_data do |c, type, data|
|
36
|
+
$stderr.print data
|
37
|
+
end
|
38
|
+
|
39
|
+
channel.on_request("exit-status") do |ch,data|
|
40
|
+
raise SshWrapper::UnexpectedExitCode unless data.read_long == 0
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
channel.wait
|
46
|
+
|
47
|
+
stdout_data.join("")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
class ConnectHypervisor
|
53
|
+
|
54
|
+
def initialize(app, env)
|
55
|
+
@app = app
|
56
|
+
@logger = Log4r::Logger.new("vagrant_smartos::action::connect_hypervisor")
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(env)
|
60
|
+
|
61
|
+
username,hostname = env[:machine].provider_config.hypervisor.split("@")
|
62
|
+
|
63
|
+
Net::SSH.start(hostname,username) do |ssh|
|
64
|
+
|
65
|
+
env[:hyp_ssh] = ssh
|
66
|
+
env[:hyp] = SshWrapper.new(ssh)
|
67
|
+
@app.call(env)
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
|
3
|
+
module Smartos
|
4
|
+
class Provider
|
5
|
+
|
6
|
+
class IsCreated
|
7
|
+
|
8
|
+
def initialize(app, env)
|
9
|
+
@app = app
|
10
|
+
@logger = Log4r::Logger.new("vagrant_smartos::action::is_created")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
|
15
|
+
env[:result] = env[:machine].state.id != :not_created
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Smartos
|
3
|
+
class Provider
|
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_smartos.already_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Smartos
|
3
|
+
class Provider
|
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_smartos.not_created"))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Smartos
|
5
|
+
class Provider
|
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_smartos::action::read_state")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
output = env[:machine].id && read_state(env[:hyp], env[:machine])
|
16
|
+
|
17
|
+
if output
|
18
|
+
env[:machine_state_id] = output["state"].to_sym
|
19
|
+
env[:machine_ssh_info] = {
|
20
|
+
:host => output["nics"].first["ip"],
|
21
|
+
:port => 22
|
22
|
+
}
|
23
|
+
else
|
24
|
+
env[:machine_state_id] = :not_created
|
25
|
+
end
|
26
|
+
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_state(hyp, machine)
|
31
|
+
begin
|
32
|
+
output = hyp.exec("vmadm get #{machine.id}")
|
33
|
+
rescue SshWrapper::UnexpectedExitCode
|
34
|
+
return :not_created
|
35
|
+
end
|
36
|
+
|
37
|
+
if output.chomp == ""
|
38
|
+
nil
|
39
|
+
else
|
40
|
+
JSON.load(output)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'uuid'
|
2
|
+
require "log4r"
|
3
|
+
require 'vagrant/util/retryable'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Smartos
|
7
|
+
class Provider
|
8
|
+
|
9
|
+
class RunInstance
|
10
|
+
include Vagrant::Util::Retryable
|
11
|
+
|
12
|
+
def initialize(app, env)
|
13
|
+
@app = app
|
14
|
+
@logger = Log4r::Logger.new("vagrant_smartos::action::run_instance")
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
|
19
|
+
image_uuid =
|
20
|
+
|
21
|
+
vlan = "" #104
|
22
|
+
nic_tag = "admin"
|
23
|
+
ip_address = "172.16.251.120"
|
24
|
+
subnet_mask = "255.255.255.0"
|
25
|
+
gateway = "172.16.251.2"
|
26
|
+
|
27
|
+
nic = {
|
28
|
+
"nic_tag" => env[:machine].provider_config.nic_tag,
|
29
|
+
"ip" => env[:machine].provider_config.ip_address,
|
30
|
+
"netmask" => env[:machine].provider_config.subnet_mask,
|
31
|
+
"gateway" => env[:machine].provider_config.gateway,
|
32
|
+
"primary" => true
|
33
|
+
}
|
34
|
+
|
35
|
+
if env[:machine].provider_config.vlan
|
36
|
+
nic["vlan_id"] = env[:machine].provider_config.vlan
|
37
|
+
end
|
38
|
+
|
39
|
+
env[:machine].id = UUID.generate
|
40
|
+
|
41
|
+
machine_json = {
|
42
|
+
"uuid" => env[:machine].id,
|
43
|
+
"brand" => "joyent",
|
44
|
+
"image_uuid" => env[:machine].provider_config.image_uuid,
|
45
|
+
"alias" => "vagrant-#{Time.now.to_i}",
|
46
|
+
"max_physical_memory" => env[:machine].provider_config.ram,
|
47
|
+
"quota" => env[:machine].provider_config.quota,
|
48
|
+
"nics" => [nic],
|
49
|
+
"customer_metadata" => {
|
50
|
+
"user-script" => "useradd -s /usr/bin/bash -m vagrant && passwd -N vagrant && mkdir -p ~vagrant/.ssh && echo 'vagrant ALL=NOPASSWD: ALL' >> /opt/local/etc/sudoers && echo 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key' >> ~vagrant/.ssh/authorized_keys"
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
|
55
|
+
# Launch!
|
56
|
+
env[:ui].info(I18n.t("vagrant_smartos.launching_instance"))
|
57
|
+
|
58
|
+
env[:hyp].exec("vmadm create <<JSON\n#{JSON.dump(machine_json)}\nJSON")
|
59
|
+
|
60
|
+
env[:ui].info(I18n.t("vagrant_smartos.waiting_for_ready"))
|
61
|
+
while true
|
62
|
+
break if env[:interrupted]
|
63
|
+
break if env[:machine].provider.state.id == :running
|
64
|
+
sleep 2
|
65
|
+
end
|
66
|
+
|
67
|
+
env[:ui].info(I18n.t("vagrant_smartos.waiting_for_ssh"))
|
68
|
+
while true
|
69
|
+
break if env[:interrupted]
|
70
|
+
break if env[:machine].communicate.ready?
|
71
|
+
sleep 2
|
72
|
+
end
|
73
|
+
|
74
|
+
if env[:interrupted]
|
75
|
+
terminate(env)
|
76
|
+
else
|
77
|
+
env[:ui].info(I18n.t("vagrant_smartos.ready"))
|
78
|
+
end
|
79
|
+
|
80
|
+
@app.call(env)
|
81
|
+
end
|
82
|
+
|
83
|
+
def recover(env)
|
84
|
+
return if env["vagrant.error"].is_a?(Vagrant::Errors::VagrantError)
|
85
|
+
|
86
|
+
if env[:machine].provider.state.id != :not_created
|
87
|
+
# Undo the import
|
88
|
+
terminate(env)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def terminate(env)
|
93
|
+
destroy_env = env.dup
|
94
|
+
destroy_env.delete(:interrupted)
|
95
|
+
destroy_env[:config_validate] = false
|
96
|
+
destroy_env[:force_confirm_destroy] = true
|
97
|
+
env[:action_runner].run(env[:machine].provider.action_destroy, destroy_env)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require "vagrant/util/subprocess"
|
4
|
+
|
5
|
+
require "vagrant/util/scoped_hash_override"
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module Smartos
|
9
|
+
class Provider
|
10
|
+
# This middleware uses `rsync` to sync the folders over to the
|
11
|
+
# AWS instance.
|
12
|
+
class SyncFolders
|
13
|
+
include Vagrant::Util::ScopedHashOverride
|
14
|
+
|
15
|
+
def initialize(app, env)
|
16
|
+
@app = app
|
17
|
+
@logger = Log4r::Logger.new("vagrant_smartos::action::sync_folders")
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
@app.call(env)
|
22
|
+
|
23
|
+
ssh_info = env[:machine].ssh_info
|
24
|
+
|
25
|
+
env[:machine].config.vm.synced_folders.each do |id, data|
|
26
|
+
data = scoped_hash_override(data, :smartos)
|
27
|
+
|
28
|
+
# Ignore disabled shared folders
|
29
|
+
next if data[:disabled]
|
30
|
+
|
31
|
+
hostpath = File.expand_path(data[:hostpath], env[:root_path])
|
32
|
+
guestpath = data[:guestpath]
|
33
|
+
|
34
|
+
# Make sure there is a trailing slash on the host path to
|
35
|
+
# avoid creating an additional directory with rsync
|
36
|
+
hostpath = "#{hostpath}/" if hostpath !~ /\/$/
|
37
|
+
|
38
|
+
env[:ui].info(I18n.t("vagrant_smartos.rsync_folder",
|
39
|
+
:hostpath => hostpath,
|
40
|
+
:guestpath => guestpath))
|
41
|
+
|
42
|
+
# Create the guest path
|
43
|
+
env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
|
44
|
+
env[:machine].communicate.sudo(
|
45
|
+
"chown #{ssh_info[:username]} '#{guestpath}'")
|
46
|
+
|
47
|
+
# Rsync over to the guest path using the SSH info
|
48
|
+
command = [
|
49
|
+
"rsync", "--verbose", "--archive", "-z",
|
50
|
+
"--exclude", ".vagrant/",
|
51
|
+
"-e", "ssh -p #{ssh_info[:port]} -o StrictHostKeyChecking=no -i '#{ssh_info[:private_key_path]}'",
|
52
|
+
hostpath,
|
53
|
+
"#{ssh_info[:username]}@#{ssh_info[:host]}:#{guestpath}"]
|
54
|
+
|
55
|
+
r = Vagrant::Util::Subprocess.execute(*command)
|
56
|
+
if r.exit_code != 0
|
57
|
+
raise Errors::RsyncError,
|
58
|
+
:guestpath => guestpath,
|
59
|
+
:hostpath => hostpath,
|
60
|
+
:stderr => r.stderr
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'uuid'
|
2
|
+
require "log4r"
|
3
|
+
require 'vagrant/util/retryable'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Smartos
|
7
|
+
class Provider
|
8
|
+
# This runs the configured instance.
|
9
|
+
class TerminateInstance
|
10
|
+
include Vagrant::Util::Retryable
|
11
|
+
|
12
|
+
def initialize(app, env)
|
13
|
+
@app = app
|
14
|
+
@logger = Log4r::Logger.new("vagrant_smartos::action::terminate_instance")
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
vm_uuid = env[:machine].id
|
19
|
+
|
20
|
+
if env[:machine].state.id != :not_created
|
21
|
+
env[:ui].info(I18n.t("vagrant_smartos.terminating"))
|
22
|
+
env[:hyp].exec("vmadm destroy #{vm_uuid}")
|
23
|
+
env[:machine].id = nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Smartos
|
3
|
+
class Config < Vagrant.plugin("2", :config)
|
4
|
+
# The hypervisor to run VMs on
|
5
|
+
#
|
6
|
+
# @return [String] (username@ipaddress)
|
7
|
+
attr_accessor :hypervisor
|
8
|
+
|
9
|
+
# The UUID of the image to use
|
10
|
+
#
|
11
|
+
# @return [String] UUID
|
12
|
+
attr_accessor :image_uuid
|
13
|
+
|
14
|
+
attr_accessor :nic_tag, :ip_address, :subnet_mask, :gateway, :vlan, :ram, :quota
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@hypervisor = UNSET_VALUE
|
18
|
+
@image_uuid = UNSET_VALUE
|
19
|
+
@nic_tag = UNSET_VALUE
|
20
|
+
@ip_address = UNSET_VALUE
|
21
|
+
@subnet_mask = UNSET_VALUE
|
22
|
+
@gateway = UNSET_VALUE
|
23
|
+
@vlan = UNSET_VALUE
|
24
|
+
@ram = UNSET_VALUE
|
25
|
+
@quota = UNSET_VALUE
|
26
|
+
@__finalized = false
|
27
|
+
end
|
28
|
+
|
29
|
+
def finalize!
|
30
|
+
@hypervisor = nil if @hypervisor == UNSET_VALUE
|
31
|
+
@image_uuid = nil if @image_uuid == UNSET_VALUE
|
32
|
+
@nic_tag = "admin" if @nic_tag == UNSET_VALUE
|
33
|
+
@ip_address = nil if @ip_address == UNSET_VALUE
|
34
|
+
@subnet_mask = nil if @subnet_mask == UNSET_VALUE
|
35
|
+
@gateway = nil if @gateway == UNSET_VALUE
|
36
|
+
@vlan = nil if @vlan == UNSET_VALUE
|
37
|
+
@ram = 256 if @ram == UNSET_VALUE
|
38
|
+
@quota = 5 if @quota == UNSET_VALUE
|
39
|
+
|
40
|
+
# Mark that we finalized
|
41
|
+
@__finalized = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate(machine)
|
45
|
+
errors = []
|
46
|
+
|
47
|
+
errors << I18n.t("vagrant_smartos.config.hypervisor_required") if @hypervisor.nil?
|
48
|
+
errors << I18n.t("vagrant_smartos.config.image_uuid_required") if @image_uuid.nil?
|
49
|
+
errors << I18n.t("vagrant_smartos.config.ip_address_required") if @ip_address.nil?
|
50
|
+
errors << I18n.t("vagrant_smartos.config.subnet_mask_required") if @subnet_mask.nil?
|
51
|
+
errors << I18n.t("vagrant_smartos.config.gateway_required") if @gateway.nil?
|
52
|
+
|
53
|
+
{ "SmartOS Provider" => errors }
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
puts "I GOT LOADED"
|
2
|
+
begin
|
3
|
+
require "vagrant"
|
4
|
+
rescue LoadError
|
5
|
+
raise "The Vagrant SmartOS plugin must be run within Vagrant."
|
6
|
+
end
|
7
|
+
|
8
|
+
# This is a sanity check to make sure no one is attempting to install
|
9
|
+
# this into an early Vagrant version.
|
10
|
+
if Vagrant::VERSION < "1.2.0"
|
11
|
+
raise "The Vagrant SmartOS plugin is only compatible with Vagrant 1.2+"
|
12
|
+
end
|
13
|
+
|
14
|
+
module VagrantPlugins
|
15
|
+
module Smartos
|
16
|
+
class Plugin < Vagrant.plugin("2")
|
17
|
+
name "SmartOS"
|
18
|
+
description <<-DESC
|
19
|
+
This plugin installs a provider that allows Vagrant to manage
|
20
|
+
machines on a SmartOS Hypervisor.
|
21
|
+
DESC
|
22
|
+
|
23
|
+
config(:smartos, :provider) do
|
24
|
+
require_relative "config"
|
25
|
+
Config
|
26
|
+
end
|
27
|
+
|
28
|
+
provider(:smartos, :parallel => true) do
|
29
|
+
# Setup logging and i18n
|
30
|
+
setup_logging
|
31
|
+
setup_i18n
|
32
|
+
|
33
|
+
# Return the provider
|
34
|
+
require_relative "provider"
|
35
|
+
Provider
|
36
|
+
end
|
37
|
+
|
38
|
+
# This initializes the internationalization strings.
|
39
|
+
def self.setup_i18n
|
40
|
+
I18n.load_path << File.expand_path("locales/en.yml", Smartos.source_root)
|
41
|
+
I18n.reload!
|
42
|
+
end
|
43
|
+
|
44
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
45
|
+
def self.setup_logging
|
46
|
+
require "log4r"
|
47
|
+
|
48
|
+
level = nil
|
49
|
+
begin
|
50
|
+
level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
|
51
|
+
rescue NameError
|
52
|
+
# This means that the logging constant wasn't found,
|
53
|
+
# which is fine. We just keep `level` as `nil`. But
|
54
|
+
# we tell the user.
|
55
|
+
level = nil
|
56
|
+
end
|
57
|
+
|
58
|
+
# Some constants, such as "true" resolve to booleans, so the
|
59
|
+
# above error checking doesn't catch it. This will check to make
|
60
|
+
# sure that the log level is an integer, as Log4r requires.
|
61
|
+
level = nil if !level.is_a?(Integer)
|
62
|
+
|
63
|
+
# Set the logging level on all "vagrant" namespaced
|
64
|
+
# logs as long as we have a valid level.
|
65
|
+
if level
|
66
|
+
logger = Log4r::Logger.new("vagrant_smartos")
|
67
|
+
logger.outputters = Log4r::Outputter.stderr
|
68
|
+
logger.level = level
|
69
|
+
logger = nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "vagrant"
|
3
|
+
require 'vagrant/action/builder'
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Smartos
|
7
|
+
class Provider < Vagrant.plugin("2", :provider)
|
8
|
+
|
9
|
+
include Vagrant::Action::Builtin
|
10
|
+
|
11
|
+
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
12
|
+
autoload :ConnectHypervisor, action_root.join("connect_hypervisor")
|
13
|
+
autoload :IsCreated, action_root.join("is_created")
|
14
|
+
autoload :MessageAlreadyCreated, action_root.join("message_already_created")
|
15
|
+
autoload :MessageNotCreated, action_root.join("message_not_created")
|
16
|
+
autoload :ReadState, action_root.join("read_state")
|
17
|
+
autoload :RunInstance, action_root.join("run_instance")
|
18
|
+
autoload :SyncFolders, action_root.join("sync_folders")
|
19
|
+
autoload :TerminateInstance, action_root.join("terminate_instance")
|
20
|
+
|
21
|
+
def initialize(machine)
|
22
|
+
@machine = machine
|
23
|
+
end
|
24
|
+
|
25
|
+
def action_up
|
26
|
+
Vagrant::Action::Builder.new.tap do |b|
|
27
|
+
b.use ConfigValidate
|
28
|
+
b.use ConnectHypervisor
|
29
|
+
b.use Call, IsCreated do |env, b2|
|
30
|
+
if env[:result]
|
31
|
+
b2.use MessageAlreadyCreated
|
32
|
+
next
|
33
|
+
end
|
34
|
+
|
35
|
+
b2.use SyncFolders
|
36
|
+
b2.use RunInstance
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def action_destroy
|
42
|
+
Vagrant::Action::Builder.new.tap do |b|
|
43
|
+
b.use ConfigValidate
|
44
|
+
b.use ConnectHypervisor
|
45
|
+
b.use TerminateInstance
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def action_provision
|
51
|
+
Vagrant::Action::Builder.new.tap do |b|
|
52
|
+
b.use ConfigValidate
|
53
|
+
b.use Call, IsCreated do |env, b2|
|
54
|
+
if !env[:result]
|
55
|
+
b2.use MessageNotCreated
|
56
|
+
next
|
57
|
+
end
|
58
|
+
|
59
|
+
b2.use Provision
|
60
|
+
b2.use SyncFolders
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def action_read_ssh_info
|
66
|
+
Vagrant::Action::Builder.new.tap do |b|
|
67
|
+
b.use ConfigValidate
|
68
|
+
b.use ConnectHypervisor
|
69
|
+
b.use ReadSSHInfo
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def action_read_state
|
74
|
+
Vagrant::Action::Builder.new.tap do |b|
|
75
|
+
b.use ConfigValidate
|
76
|
+
b.use ConnectHypervisor
|
77
|
+
b.use ReadState
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def action_ssh
|
82
|
+
Vagrant::Action::Builder.new.tap do |b|
|
83
|
+
b.use ConfigValidate
|
84
|
+
b.use Call, IsCreated do |env, b2|
|
85
|
+
if !env[:result]
|
86
|
+
b2.use MessageNotCreated
|
87
|
+
next
|
88
|
+
end
|
89
|
+
|
90
|
+
b2.use SSHExec
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def action_ssh_run
|
96
|
+
Vagrant::Action::Builder.new.tap do |b|
|
97
|
+
b.use ConfigValidate
|
98
|
+
b.use Call, IsCreated do |env, b2|
|
99
|
+
if !env[:result]
|
100
|
+
b2.use MessageNotCreated
|
101
|
+
next
|
102
|
+
end
|
103
|
+
|
104
|
+
b2.use SSHRun
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
def action(name)
|
111
|
+
case name.intern
|
112
|
+
when :up
|
113
|
+
action_up
|
114
|
+
when :read_state
|
115
|
+
action_read_state
|
116
|
+
when :destroy
|
117
|
+
action_destroy
|
118
|
+
when :ssh
|
119
|
+
action_ssh
|
120
|
+
when :ssh_run
|
121
|
+
action_ssh_run
|
122
|
+
when :provision
|
123
|
+
action_provision
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def ssh_info
|
128
|
+
# Run a custom action called "read_ssh_info" which does what it
|
129
|
+
# says and puts the resulting SSH info into the `:machine_ssh_info`
|
130
|
+
# key in the environment.
|
131
|
+
env = @machine.action("read_state")
|
132
|
+
|
133
|
+
env[:machine_ssh_info]
|
134
|
+
end
|
135
|
+
|
136
|
+
def state
|
137
|
+
# Run a custom action we define called "read_state" which does
|
138
|
+
# what it says. It puts the state in the `:machine_state_id`
|
139
|
+
# key in the environment.
|
140
|
+
env = @machine.action("read_state")
|
141
|
+
|
142
|
+
state_id = env[:machine_state_id]
|
143
|
+
|
144
|
+
# Get the short and long description
|
145
|
+
short = I18n.t("vagrant_smartos.states.short_#{state_id}")
|
146
|
+
long = I18n.t("vagrant_smartos.states.long_#{state_id}")
|
147
|
+
|
148
|
+
# Return the MachineState object
|
149
|
+
Vagrant::MachineState.new(state_id, short, long)
|
150
|
+
end
|
151
|
+
|
152
|
+
def to_s
|
153
|
+
id = @machine.id.nil? ? "new" : @machine.id
|
154
|
+
"SmartOS (#{id})"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
require "vagrant-smartos/version"
|
4
|
+
require 'vagrant-smartos/plugin'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module Smartos
|
8
|
+
lib_path = Pathname.new(File.expand_path("../vagrant-smartos", __FILE__))
|
9
|
+
#autoload :Action, lib_path.join("action")
|
10
|
+
#autoload :Errors, lib_path.join("errors")
|
11
|
+
|
12
|
+
# This returns the path to the source of this plugin.
|
13
|
+
#
|
14
|
+
# @return [Pathname]
|
15
|
+
def self.source_root
|
16
|
+
@source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
data/locales/en.yml
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
en:
|
2
|
+
vagrant_smartos:
|
3
|
+
config:
|
4
|
+
hypervisor_required: |-
|
5
|
+
A hypervisor must be specified
|
6
|
+
|
7
|
+
image_uuid_required: |-
|
8
|
+
An image_uuid value is required
|
9
|
+
|
10
|
+
states:
|
11
|
+
running_short: |-
|
12
|
+
Running
|
13
|
+
running_long: |-
|
14
|
+
Running
|
15
|
+
|
16
|
+
not_created: |-
|
17
|
+
Not CREATED!
|
18
|
+
|
19
|
+
already_created: |-
|
20
|
+
ALREADY CREATED!
|
21
|
+
|
22
|
+
launching_instance: |-
|
23
|
+
Yo, launching an instance, innit.
|
24
|
+
|
25
|
+
waiting_for_ready: |-
|
26
|
+
Yar, this is taking time. Hang on...
|
27
|
+
|
28
|
+
waiting_for_ssh: |-
|
29
|
+
FFS. Should be done now. Still farting around with SSH.
|
30
|
+
|
31
|
+
ready: |-
|
32
|
+
Finally, the bastard is ready.
|
33
|
+
|
34
|
+
rsync_folder: |-
|
35
|
+
Fucker is out of date. Updating.
|
36
|
+
|
37
|
+
terminating: |-
|
38
|
+
Yeah, I didn't really like it either.
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'vagrant-smartos/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "vagrant-smartos"
|
8
|
+
gem.version = Vagrant::Smartos::VERSION
|
9
|
+
gem.authors = ["Thomas Haggett"]
|
10
|
+
gem.email = ["thomas@haggett.org"]
|
11
|
+
gem.description = %q{SmartOS Hypervisor provider for Vagrant}
|
12
|
+
gem.summary = %q{SmartOS Hypervisor provider for Vagrant}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency "uuid"
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-smartos
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: true
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1alpha
|
9
|
+
version: 0.0.1alpha
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Thomas Haggett
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2013-06-06 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: uuid
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: SmartOS Hypervisor provider for Vagrant
|
33
|
+
email:
|
34
|
+
- thomas@haggett.org
|
35
|
+
executables: []
|
36
|
+
|
37
|
+
extensions: []
|
38
|
+
|
39
|
+
extra_rdoc_files: []
|
40
|
+
|
41
|
+
files:
|
42
|
+
- .gitignore
|
43
|
+
- Gemfile
|
44
|
+
- LICENSE.txt
|
45
|
+
- README.md
|
46
|
+
- Rakefile
|
47
|
+
- Vagrantfile
|
48
|
+
- example_box/Vagrantfile
|
49
|
+
- example_box/metadata.json
|
50
|
+
- example_box/smartos.box
|
51
|
+
- lib/vagrant-smartos.rb
|
52
|
+
- lib/vagrant-smartos/action/connect_hypervisor.rb
|
53
|
+
- lib/vagrant-smartos/action/is_created.rb
|
54
|
+
- lib/vagrant-smartos/action/message_already_created.rb
|
55
|
+
- lib/vagrant-smartos/action/message_not_created.rb
|
56
|
+
- lib/vagrant-smartos/action/read_state.rb
|
57
|
+
- lib/vagrant-smartos/action/run_instance.rb
|
58
|
+
- lib/vagrant-smartos/action/sync_folders.rb
|
59
|
+
- lib/vagrant-smartos/action/terminate_instance.rb
|
60
|
+
- lib/vagrant-smartos/config.rb
|
61
|
+
- lib/vagrant-smartos/plugin.rb
|
62
|
+
- lib/vagrant-smartos/provider.rb
|
63
|
+
- lib/vagrant-smartos/version.rb
|
64
|
+
- locales/en.yml
|
65
|
+
- vagrant-smartos.gemspec
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: ""
|
68
|
+
licenses: []
|
69
|
+
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">"
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
segments:
|
87
|
+
- 1
|
88
|
+
- 3
|
89
|
+
- 1
|
90
|
+
version: 1.3.1
|
91
|
+
requirements: []
|
92
|
+
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 1.3.6
|
95
|
+
signing_key:
|
96
|
+
specification_version: 3
|
97
|
+
summary: SmartOS Hypervisor provider for Vagrant
|
98
|
+
test_files: []
|
99
|
+
|