vagrant-dustcloud 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/Gemfile +9 -0
- data/README.md +56 -0
- data/Rakefile +14 -0
- data/dummy.box +0 -0
- data/example_box/README.md +0 -0
- data/example_box/metadata.json +3 -0
- data/lib/vagrant-dustcloud.rb +18 -0
- data/lib/vagrant-dustcloud/action.rb +189 -0
- data/lib/vagrant-dustcloud/action/connect_dustcloud.rb +65 -0
- data/lib/vagrant-dustcloud/action/is_created.rb +18 -0
- data/lib/vagrant-dustcloud/action/is_stopped.rb +18 -0
- data/lib/vagrant-dustcloud/action/message_already_created.rb +16 -0
- data/lib/vagrant-dustcloud/action/message_not_created.rb +16 -0
- data/lib/vagrant-dustcloud/action/message_will_not_destroy.rb +16 -0
- data/lib/vagrant-dustcloud/action/read_ssh_info.rb +38 -0
- data/lib/vagrant-dustcloud/action/read_state.rb +33 -0
- data/lib/vagrant-dustcloud/action/run_instance.rb +110 -0
- data/lib/vagrant-dustcloud/action/start_instance.rb +82 -0
- data/lib/vagrant-dustcloud/action/stop_instance.rb +26 -0
- data/lib/vagrant-dustcloud/action/terminate_instance.rb +32 -0
- data/lib/vagrant-dustcloud/action/timed_provision.rb +21 -0
- data/lib/vagrant-dustcloud/action/wait_for_state.rb +41 -0
- data/lib/vagrant-dustcloud/config.rb +52 -0
- data/lib/vagrant-dustcloud/errors.rb +23 -0
- data/lib/vagrant-dustcloud/plugin.rb +38 -0
- data/lib/vagrant-dustcloud/provider.rb +49 -0
- data/lib/vagrant-dustcloud/util/timer.rb +17 -0
- data/lib/vagrant-dustcloud/version.rb +5 -0
- data/locales/en.yaml +71 -0
- data/vagrant-dustcloud.gemspec +50 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 272a9f6a7493a0e03ad17e99ae2f3645a2cf379f462e648c744d2029c8d96f90
|
4
|
+
data.tar.gz: cba88ed71023e27524ea5847cc5ad7f5e52004daf9daa0aac483b14a20069dd3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3a6acacca644325a3f45971a39079821c1c6925a92b04917fae2f550e7c3838a1c3cc2dc4d321cfe7bf292138a0eaeac418d5a949f5f5c5f7ac142f3d2368741
|
7
|
+
data.tar.gz: be4d1851abbfd48b58da6ecf45c34e132b30d1a27520370c37e63ba9507e6da665b705eac271da2e2b9bead989c9332420e8fa20c08e5497f2e67c5ff243de1c
|
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
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/Vagrantfile
|
18
|
+
|
19
|
+
# RVM files for gemset/ruby setting
|
20
|
+
.ruby-*
|
21
|
+
.rvmrc
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# Vagrant LUDD DUSTcloud Provider
|
2
|
+
|
3
|
+
## Features
|
4
|
+
- Boot instances in LUDD DUSTcloud.
|
5
|
+
- SSH into the instances.
|
6
|
+
- Provision the instances with any built-in Vagrant provisioner.
|
7
|
+
- Minimal synced folder support via `rsync`.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
Install using the standard Vagrant 1.1+ plugin installation methods. After installing, `vagrant up` and specify the `dustcloud` provider. An example is shown below.
|
11
|
+
```
|
12
|
+
$ vagrant plugin install vagrant-dustcloud
|
13
|
+
...
|
14
|
+
$ vagrant up --provider=dustcloud
|
15
|
+
...
|
16
|
+
```
|
17
|
+
|
18
|
+
## Quick Start
|
19
|
+
After installing the plugin (instructions above), the quickest way to get started is to actually use a dummy Dustcloud box and specify all the details manually within a config.vm.provider block. So first, add the dummy box using any name you want:
|
20
|
+
```
|
21
|
+
$ vagrant box add dummy https://git.ludd.ltu.se/ludd/vagrant-dustcloud/raw/master/dummy.box
|
22
|
+
...
|
23
|
+
```
|
24
|
+
And then make a Vagrantfile that looks like the following.
|
25
|
+
```ruby
|
26
|
+
Vagrant.configure("2") do |config|
|
27
|
+
config.vm.box = "dummy"
|
28
|
+
|
29
|
+
config.vm.provider :dustcloud do |dustcloud|
|
30
|
+
dustcloud.token_file = "~/.dustcloud"
|
31
|
+
dustcloud.image = "focal"
|
32
|
+
dustcloud.flavor = "small"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
```
|
36
|
+
And then run `vagrant up --provider=dustcloud`.
|
37
|
+
|
38
|
+
## Development
|
39
|
+
To work on the `vagrant-dustcloud` plugin, clone this repository out, and use
|
40
|
+
[Bundler](http://gembundler.com) to get the dependencies:
|
41
|
+
|
42
|
+
```
|
43
|
+
$ bundle
|
44
|
+
```
|
45
|
+
|
46
|
+
If those pass, you're ready to start developing the plugin. You can test
|
47
|
+
the plugin without installing it into your Vagrant environment by just
|
48
|
+
creating a `Vagrantfile` in the top level of this directory (it is gitignored)
|
49
|
+
and add the following line to your `Vagrantfile`
|
50
|
+
```ruby
|
51
|
+
Vagrant.require_plugin "vagrant-dustcloud"
|
52
|
+
```
|
53
|
+
Use bundler to execute Vagrant:
|
54
|
+
```
|
55
|
+
$ bundle exec vagrant up --provider=dustcloud
|
56
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
# Immediately sync all stdout so that tools like buildbot can
|
5
|
+
# immediately load in the output.
|
6
|
+
$stdout.sync = true
|
7
|
+
$stderr.sync = true
|
8
|
+
|
9
|
+
# Change to the directory of this file.
|
10
|
+
Dir.chdir(File.expand_path("../", __FILE__))
|
11
|
+
|
12
|
+
# This installs the tasks that help with gem creation and
|
13
|
+
# publishing.
|
14
|
+
Bundler::GemHelper.install_tasks
|
data/dummy.box
ADDED
Binary file
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
require "vagrant-dustcloud/plugin"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Dustcloud
|
7
|
+
lib_path = Pathname.new(File.expand_path("../vagrant-dustcloud", __FILE__))
|
8
|
+
autoload :Action, lib_path.join("action")
|
9
|
+
autoload :Errors, lib_path.join("errors")
|
10
|
+
|
11
|
+
# This returns the path to the source of this plugin.
|
12
|
+
#
|
13
|
+
# @return [Pathname]
|
14
|
+
def self.source_root
|
15
|
+
@source_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,189 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
require "vagrant/action/builder"
|
4
|
+
|
5
|
+
module VagrantPlugins
|
6
|
+
module Dustcloud
|
7
|
+
module Action
|
8
|
+
# Include the built-in modules so we can use them as top-level things.
|
9
|
+
include Vagrant::Action::Builtin
|
10
|
+
|
11
|
+
# This action is called to halt the remote machine.
|
12
|
+
def self.action_halt
|
13
|
+
Vagrant::Action::Builder.new.tap do |b|
|
14
|
+
b.use ConfigValidate
|
15
|
+
b.use Call, IsCreated do |env, b2|
|
16
|
+
if !env[:result]
|
17
|
+
b2.use MessageNotCreated
|
18
|
+
next
|
19
|
+
end
|
20
|
+
|
21
|
+
b2.use ConnectDustcloud
|
22
|
+
b2.use StopInstance
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# This action is called to terminate the remote machine.
|
28
|
+
def self.action_destroy
|
29
|
+
Vagrant::Action::Builder.new.tap do |b|
|
30
|
+
b.use Call, DestroyConfirm do |env, b2|
|
31
|
+
if env[:result]
|
32
|
+
b2.use ConfigValidate
|
33
|
+
b2.use Call, IsCreated do |env2, b3|
|
34
|
+
if !env2[:result]
|
35
|
+
b3.use MessageNotCreated
|
36
|
+
next
|
37
|
+
end
|
38
|
+
|
39
|
+
b3.use ConnectDustcloud
|
40
|
+
b3.use ProvisionerCleanup, :before if defined?(ProvisionerCleanup)
|
41
|
+
b3.use TerminateInstance
|
42
|
+
end
|
43
|
+
else
|
44
|
+
b2.use MessageWillNotDestroy
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# This action is called when `vagrant provision` is called.
|
51
|
+
def self.action_provision
|
52
|
+
Vagrant::Action::Builder.new.tap do |b|
|
53
|
+
b.use ConfigValidate
|
54
|
+
b.use Call, IsCreated do |env, b2|
|
55
|
+
if !env[:result]
|
56
|
+
b2.use MessageNotCreated
|
57
|
+
next
|
58
|
+
end
|
59
|
+
|
60
|
+
b2.use Provision
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# This action is called to read the SSH info of the machine. The
|
66
|
+
# resulting state is expected to be put into the `:machine_ssh_info`
|
67
|
+
# key.
|
68
|
+
def self.action_read_ssh_info
|
69
|
+
Vagrant::Action::Builder.new.tap do |b|
|
70
|
+
b.use ConfigValidate
|
71
|
+
b.use ConnectDustcloud
|
72
|
+
b.use ReadSSHInfo
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# This action is called to read the state of the machine. The
|
77
|
+
# resulting state is expected to be put into the `:machine_state_id`
|
78
|
+
# key.
|
79
|
+
def self.action_read_state
|
80
|
+
Vagrant::Action::Builder.new.tap do |b|
|
81
|
+
b.use ConfigValidate
|
82
|
+
b.use ConnectDustcloud
|
83
|
+
b.use ReadState
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# This action is called to SSH into the machine.
|
88
|
+
def self.action_ssh
|
89
|
+
Vagrant::Action::Builder.new.tap do |b|
|
90
|
+
b.use ConfigValidate
|
91
|
+
b.use Call, IsCreated do |env, b2|
|
92
|
+
if !env[:result]
|
93
|
+
b2.use MessageNotCreated
|
94
|
+
next
|
95
|
+
end
|
96
|
+
|
97
|
+
b2.use SSHExec
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.action_ssh_run
|
103
|
+
Vagrant::Action::Builder.new.tap do |b|
|
104
|
+
b.use ConfigValidate
|
105
|
+
b.use Call, IsCreated do |env, b2|
|
106
|
+
if !env[:result]
|
107
|
+
b2.use MessageNotCreated
|
108
|
+
next
|
109
|
+
end
|
110
|
+
|
111
|
+
b2.use SSHRun
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.action_prepare_boot
|
117
|
+
Vagrant::Action::Builder.new.tap do |b|
|
118
|
+
b.use Provision
|
119
|
+
b.use SyncedFolders
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# This action is called to bring the box up from nothing.
|
124
|
+
def self.action_up
|
125
|
+
Vagrant::Action::Builder.new.tap do |b|
|
126
|
+
b.use HandleBox
|
127
|
+
b.use ConfigValidate
|
128
|
+
b.use BoxCheckOutdated
|
129
|
+
b.use ConnectDustcloud
|
130
|
+
b.use Call, IsCreated do |env1, b1|
|
131
|
+
if env1[:result]
|
132
|
+
b1.use Call, IsStopped do |env2, b2|
|
133
|
+
if env2[:result]
|
134
|
+
b2.use action_prepare_boot
|
135
|
+
b2.use StartInstance # restart this instance
|
136
|
+
else
|
137
|
+
b2.use MessageAlreadyCreated # TODO write a better message
|
138
|
+
end
|
139
|
+
end
|
140
|
+
else
|
141
|
+
b1.use action_prepare_boot
|
142
|
+
b1.use RunInstance # launch a new instance
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def self.action_reload
|
149
|
+
Vagrant::Action::Builder.new.tap do |b|
|
150
|
+
b.use ConfigValidate
|
151
|
+
b.use ConnectDustcloud
|
152
|
+
b.use Call, IsCreated do |env, b2|
|
153
|
+
if !env[:result]
|
154
|
+
b2.use MessageNotCreated
|
155
|
+
next
|
156
|
+
end
|
157
|
+
|
158
|
+
b2.use action_halt
|
159
|
+
b2.use Call, WaitForState, :shutoff, 120 do |env2, b3|
|
160
|
+
if env2[:result]
|
161
|
+
b3.use action_up
|
162
|
+
else
|
163
|
+
# TODO we couldn't reach :stopped, what now?
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# The autoload farm
|
171
|
+
action_root = Pathname.new(File.expand_path("../action", __FILE__))
|
172
|
+
autoload :ConnectDustcloud, action_root.join("connect_dustcloud")
|
173
|
+
autoload :IsCreated, action_root.join("is_created")
|
174
|
+
autoload :IsStopped, action_root.join("is_stopped")
|
175
|
+
autoload :MessageAlreadyCreated, action_root.join("message_already_created")
|
176
|
+
autoload :MessageNotCreated, action_root.join("message_not_created")
|
177
|
+
autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
|
178
|
+
autoload :PackageInstance, action_root.join("package_instance")
|
179
|
+
autoload :ReadSSHInfo, action_root.join("read_ssh_info")
|
180
|
+
autoload :ReadState, action_root.join("read_state")
|
181
|
+
autoload :RunInstance, action_root.join("run_instance")
|
182
|
+
autoload :StartInstance, action_root.join("start_instance")
|
183
|
+
autoload :StopInstance, action_root.join("stop_instance")
|
184
|
+
autoload :TerminateInstance, action_root.join("terminate_instance")
|
185
|
+
autoload :TimedProvision, action_root.join("timed_provision") # some plugins now expect this action to exist
|
186
|
+
autoload :WaitForState, action_root.join("wait_for_state")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
require 'net/http'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module Dustcloud
|
8
|
+
module Action
|
9
|
+
class ConnectDustcloud
|
10
|
+
def initialize(app, env)
|
11
|
+
@app = app
|
12
|
+
@logger = Log4r::Logger.new("vagrant_dustcloud::action::connect_dustcloud")
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
|
17
|
+
api_token = env[:machine].provider_config.token.to_s
|
18
|
+
env[:dustcloud] = DustcloudAPI.new(api_token)
|
19
|
+
|
20
|
+
pw_file = env[:machine].data_dir.join('ssh_password')
|
21
|
+
if pw_file.file?
|
22
|
+
env[:machine_ssh_password] = pw_file.read
|
23
|
+
end
|
24
|
+
|
25
|
+
@app.call(env)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class DustcloudAPI
|
30
|
+
def initialize(api_token)
|
31
|
+
net = Net::HTTP.new("dust.ludd.ltu.se", 443)
|
32
|
+
net.use_ssl = true
|
33
|
+
@api_token = api_token
|
34
|
+
@net = net
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_vm(uuid)
|
38
|
+
res = @net.get("/cloud/vm/#{uuid}", "X-Dustcloud-Token" => @api_token )
|
39
|
+
JSON.parse(res.body)
|
40
|
+
end
|
41
|
+
|
42
|
+
def create_vm(image, flavor)
|
43
|
+
res = @net.post("/cloud/new", "image=#{image}&flavor=#{flavor}", "x-dustcloud-token" => @api_token )
|
44
|
+
JSON.parse(res.body)
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def start_vm(uuid)
|
49
|
+
res = @net.post("/cloud/vm/#{uuid}/start", "", "x-dustcloud-token" => @api_token)
|
50
|
+
JSON.parse(res.body)
|
51
|
+
end
|
52
|
+
|
53
|
+
def stop_vm(uuid)
|
54
|
+
res = @net.post("/cloud/vm/#{uuid}/stop", "", "x-dustcloud-token" => @api_token)
|
55
|
+
JSON.parse(res.body)
|
56
|
+
end
|
57
|
+
|
58
|
+
def destroy_vm(uuid)
|
59
|
+
res = @net.post("/cloud/vm/#{uuid}/delete", "", "x-dustcloud-token" => @api_token)
|
60
|
+
JSON.parse(res.body)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Dustcloud
|
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].state.id != :not_created
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Dustcloud
|
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 == :shutoff
|
13
|
+
@app.call(env)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Dustcloud
|
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_dustcloud.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 Dustcloud
|
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_dustcloud.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 Dustcloud
|
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_dustcloud.will_not_destroy", name: env[:machine].name))
|
11
|
+
@app.call(env)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
5
|
+
module Action
|
6
|
+
# This action reads the SSH info for the machine and puts it into the
|
7
|
+
# `:machine_ssh_info` key in the environment.
|
8
|
+
class ReadSSHInfo
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new("vagrant_dustcloud::action::read_ssh_info")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
env[:machine_ssh_info] = read_ssh_info(env[:dustcloud], env)
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_ssh_info(dustcloud, env)
|
21
|
+
machine = env[:machine]
|
22
|
+
return nil if machine.id.nil?
|
23
|
+
|
24
|
+
# Find the machine
|
25
|
+
server = dustcloud.get_vm(machine.id)
|
26
|
+
if server.nil?
|
27
|
+
# The machine can't be found
|
28
|
+
@logger.info("Machine couldn't be found, assuming it got destroyed.")
|
29
|
+
machine.id = nil
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
return { :host => server["ssh_host"], :port => server["ssh_port"], :username => server["ssh_username"], :password => env[:machine_ssh_password] }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
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_dustcloud::action::read_state")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
env[:machine_state_id] = read_state(env[:dustcloud], env[:machine])
|
16
|
+
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
def read_state(dustcloud, machine)
|
21
|
+
return :not_created if machine.id.nil?
|
22
|
+
|
23
|
+
# Find the machine
|
24
|
+
server = dustcloud.get_vm(machine.id)
|
25
|
+
if server.nil?
|
26
|
+
return :not_created
|
27
|
+
end
|
28
|
+
return server["status"].downcase.to_sym
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
require 'vagrant/util/retryable'
|
5
|
+
require 'vagrant-dustcloud/util/timer'
|
6
|
+
|
7
|
+
module VagrantPlugins
|
8
|
+
module Dustcloud
|
9
|
+
module Action
|
10
|
+
# This runs the configured instance.
|
11
|
+
class RunInstance
|
12
|
+
include Vagrant::Util::Retryable
|
13
|
+
|
14
|
+
def initialize(app, env)
|
15
|
+
@app = app
|
16
|
+
@logger = Log4r::Logger.new("vagrant_dustcloud::action::run_instance")
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
# Initialize metrics if they haven't been
|
21
|
+
env[:metrics] ||= {}
|
22
|
+
|
23
|
+
flavor = env[:machine].provider_config.flavor.to_s
|
24
|
+
image = env[:machine].provider_config.image.to_s
|
25
|
+
|
26
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.launching_instance"))
|
27
|
+
env[:ui].info(" -- Image: #{image}")
|
28
|
+
env[:ui].info(" -- Flavor: #{flavor}")
|
29
|
+
|
30
|
+
begin
|
31
|
+
server = env[:dustcloud].create_vm(image, flavor)
|
32
|
+
end
|
33
|
+
|
34
|
+
env[:machine].id = server["uuid"]
|
35
|
+
env[:machine_ssh_username] = server["username"]
|
36
|
+
env[:machine_ssh_password] = server["password"]
|
37
|
+
pw_file = env[:machine].data_dir.join('ssh_password')
|
38
|
+
pw_file.open('w+') do |f|
|
39
|
+
f.write(server["password"])
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
env[:metrics]["instance_ready_time"] = Util::Timer.time do
|
45
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.waiting_for_ready"))
|
46
|
+
total_waited = 0
|
47
|
+
while true
|
48
|
+
# If we're interrupted don't worry about waiting
|
49
|
+
break if env[:interrupted]
|
50
|
+
|
51
|
+
# Wait for the server to be ready
|
52
|
+
vm = env[:dustcloud].get_vm(server["uuid"])
|
53
|
+
if vm["status"] == "ACTIVE"
|
54
|
+
break
|
55
|
+
end
|
56
|
+
sleep(2)
|
57
|
+
total_waited += 2
|
58
|
+
if total_waited > 180
|
59
|
+
raise Errors::InstanceReadyTimeout, timeout: 180
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
env[:ui].info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
|
65
|
+
if !env[:interrupted]
|
66
|
+
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
|
67
|
+
# Wait for SSH to be ready.
|
68
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.waiting_for_ssh"))
|
69
|
+
network_ready_retries = 0
|
70
|
+
network_ready_retries_max = 10
|
71
|
+
while true
|
72
|
+
# If we're interrupted then just back out
|
73
|
+
break if env[:interrupted]
|
74
|
+
# When an ec2 instance comes up, it's networking may not be ready
|
75
|
+
# by the time we connect.
|
76
|
+
begin
|
77
|
+
break if env[:machine].communicate.ready?
|
78
|
+
rescue Exception => e
|
79
|
+
if network_ready_retries < network_ready_retries_max then
|
80
|
+
network_ready_retries += 1
|
81
|
+
@logger.warn("SSH not yet up, retrying...")
|
82
|
+
else
|
83
|
+
raise e
|
84
|
+
end
|
85
|
+
end
|
86
|
+
sleep 2
|
87
|
+
end
|
88
|
+
end
|
89
|
+
env[:ui].info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
90
|
+
|
91
|
+
# Ready and booted!
|
92
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.ready"))
|
93
|
+
end
|
94
|
+
|
95
|
+
terminate(env) if env[:interrupted]
|
96
|
+
|
97
|
+
@app.call(env)
|
98
|
+
end
|
99
|
+
|
100
|
+
def terminate(env)
|
101
|
+
destroy_env = env.dup
|
102
|
+
destroy_env.delete(:interrupted)
|
103
|
+
destroy_env[:config_validate] = false
|
104
|
+
destroy_env[:force_confirm_destroy] = true
|
105
|
+
env[:action_runner].run(Action.action_destroy, destroy_env)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
require 'vagrant/util/retryable'
|
4
|
+
require 'vagrant-dustcloud/util/timer'
|
5
|
+
|
6
|
+
module VagrantPlugins
|
7
|
+
module Dustcloud
|
8
|
+
module Action
|
9
|
+
# This starts a stopped instance.
|
10
|
+
class StartInstance
|
11
|
+
|
12
|
+
def initialize(app, env)
|
13
|
+
@app = app
|
14
|
+
@logger = Log4r::Logger.new("vagrant_dustcloud::action::start_instance")
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
# Initialize metrics if they haven't been
|
19
|
+
env[:metrics] ||= {}
|
20
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.starting"))
|
21
|
+
|
22
|
+
begin
|
23
|
+
env[:dustcloud].start_vm(env[:machine].id)
|
24
|
+
|
25
|
+
env[:metrics]["instance_ready_time"] = Util::Timer.time do
|
26
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.waiting_for_ready"))
|
27
|
+
total_waited = 0
|
28
|
+
while true
|
29
|
+
# If we're interrupted don't worry about waiting
|
30
|
+
break if env[:interrupted]
|
31
|
+
|
32
|
+
# Wait for the server to be ready
|
33
|
+
vm = env[:dustcloud].get_vm(env[:machine].id)
|
34
|
+
if vm["status"] == "ACTIVE"
|
35
|
+
break
|
36
|
+
end
|
37
|
+
sleep(2)
|
38
|
+
total_waited += 2
|
39
|
+
if total_waited > 180
|
40
|
+
raise Errors::InstanceReadyTimeout, timeout: 180
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
env[:ui].info("Time to instance ready: #{env[:metrics]["instance_ready_time"]}")
|
46
|
+
if !env[:interrupted]
|
47
|
+
env[:metrics]["instance_ssh_time"] = Util::Timer.time do
|
48
|
+
# Wait for SSH to be ready.
|
49
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.waiting_for_ssh"))
|
50
|
+
network_ready_retries = 0
|
51
|
+
network_ready_retries_max = 10
|
52
|
+
while true
|
53
|
+
# If we're interrupted then just back out
|
54
|
+
break if env[:interrupted]
|
55
|
+
# When an ec2 instance comes up, it's networking may not be ready
|
56
|
+
# by the time we connect.
|
57
|
+
begin
|
58
|
+
break if env[:machine].communicate.ready?
|
59
|
+
rescue Exception => e
|
60
|
+
if network_ready_retries < network_ready_retries_max then
|
61
|
+
network_ready_retries += 1
|
62
|
+
@logger.warn("SSH not yet up, retrying...")
|
63
|
+
else
|
64
|
+
raise e
|
65
|
+
end
|
66
|
+
end
|
67
|
+
sleep 2
|
68
|
+
end
|
69
|
+
end
|
70
|
+
env[:ui].info("Time for SSH ready: #{env[:metrics]["instance_ssh_time"]}")
|
71
|
+
|
72
|
+
# Ready and booted!
|
73
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.ready"))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
@app.call(env)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "log4r"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
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_dustcloud::action::stop_instance")
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
if env[:machine].state.id == :shutoff
|
15
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.already_status", :status => env[:machine].state.id))
|
16
|
+
else
|
17
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.stopping"))
|
18
|
+
env[:dustcloud].stop_vm(env[:machine].id)
|
19
|
+
end
|
20
|
+
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Dustcloud
|
6
|
+
module Action
|
7
|
+
# This terminates the running instance.
|
8
|
+
class TerminateInstance
|
9
|
+
def initialize(app, env)
|
10
|
+
@app = app
|
11
|
+
@logger = Log4r::Logger.new("vagrant_aws::action::terminate_instance")
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
|
16
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.terminating"))
|
17
|
+
result = env[:dustcloud].destroy_vm(env[:machine].id)
|
18
|
+
if result["errors"].length > 0
|
19
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.terminating_failed"))
|
20
|
+
result["errors"].each do |item|
|
21
|
+
env[:ui].info(" -- #{item}")
|
22
|
+
end
|
23
|
+
env[:ui].info(I18n.t("vagrant_dustcloud.terminating_help"))
|
24
|
+
end
|
25
|
+
env[:machine].id = nil
|
26
|
+
|
27
|
+
@app.call(env)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "vagrant-aws/util/timer"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module AWS
|
5
|
+
module Action
|
6
|
+
# This is the same as the builtin provision except it times the
|
7
|
+
# provisioner runs.
|
8
|
+
class TimedProvision < Vagrant::Action::Builtin::Provision
|
9
|
+
def run_provisioner(env, name, p)
|
10
|
+
timer = Util::Timer.time do
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
env[:metrics] ||= {}
|
15
|
+
env[:metrics]["provisioner_times"] ||= []
|
16
|
+
env[:metrics]["provisioner_times"] << [name, timer]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "log4r"
|
2
|
+
require "timeout"
|
3
|
+
|
4
|
+
module VagrantPlugins
|
5
|
+
module Dustcloud
|
6
|
+
module Action
|
7
|
+
# This action will wait for a machine to reach a specific state or quit by timeout
|
8
|
+
class WaitForState
|
9
|
+
# env[:result] will be false in case of timeout.
|
10
|
+
# @param [Symbol] state Target machine state.
|
11
|
+
# @param [Number] timeout Timeout in seconds.
|
12
|
+
def initialize(app, env, state, timeout)
|
13
|
+
@app = app
|
14
|
+
@logger = Log4r::Logger.new("vagrant_dustcloud::action::wait_for_state")
|
15
|
+
@state = state
|
16
|
+
@timeout = timeout
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(env)
|
20
|
+
env[:result] = true
|
21
|
+
if env[:machine].state.id == @state
|
22
|
+
@logger.info("Status of machine is already #{@state}")
|
23
|
+
else
|
24
|
+
@logger.info("Waiting for machine to reach state #{@state}")
|
25
|
+
begin
|
26
|
+
Timeout.timeout(@timeout) do
|
27
|
+
until env[:machine].state.id == @state
|
28
|
+
sleep 2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
rescue Timeout::Error
|
32
|
+
env[:result] = false # couldn't reach state in time
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@app.call(env)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
5
|
+
class Config < Vagrant.plugin("2", :config)
|
6
|
+
# @return [String]
|
7
|
+
attr_accessor :token_file
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
attr_accessor :token
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
attr_accessor :image
|
14
|
+
|
15
|
+
# @return [String]
|
16
|
+
attr_accessor :flavor
|
17
|
+
|
18
|
+
def initialize()
|
19
|
+
@token_file = UNSET_VALUE
|
20
|
+
@token = UNSET_VALUE
|
21
|
+
@image = UNSET_VALUE
|
22
|
+
@flavor = UNSET_VALUE
|
23
|
+
end
|
24
|
+
|
25
|
+
def finalize!
|
26
|
+
@token_file = ENV['HOME'].to_s + '/.dustcloud' if @token_file == UNSET_VALUE
|
27
|
+
@token = Credentials.new.get_token(@token_file) if @token == UNSET_VALUE
|
28
|
+
@image = nil if @image == UNSET_VALUE
|
29
|
+
@flavor = "tiny" if @flavor == UNSET_VALUE
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate(machine)
|
33
|
+
errors = _detected_errors
|
34
|
+
|
35
|
+
errors << "No token specified" if @token.nil? || @token == ""
|
36
|
+
errors << "No image specified" if @image.nil? || @image == ""
|
37
|
+
|
38
|
+
{ "LUDD DUSTCloud Provider" => errors }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Credentials < Vagrant.plugin("2", :config)
|
43
|
+
def get_token(token_file)
|
44
|
+
if !token_file.nil? && File.exists?(token_file)
|
45
|
+
File.read(token_file)
|
46
|
+
else
|
47
|
+
ENV["DUSTCLOUD_TOKEN"].to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
5
|
+
module Errors
|
6
|
+
class VagrantDustcloudError < Vagrant::Errors::VagrantError
|
7
|
+
error_namespace("vagrant_dustcloud.errors")
|
8
|
+
end
|
9
|
+
|
10
|
+
class APIError < VagrantDustcloudError
|
11
|
+
error_key(:api_error)
|
12
|
+
end
|
13
|
+
|
14
|
+
class InternalAPIError < VagrantDustcloudError
|
15
|
+
error_key(:internal_api_error)
|
16
|
+
end
|
17
|
+
|
18
|
+
class InstanceReadyTimeout < VagrantDustcloudError
|
19
|
+
error_key(:instance_ready_timeout)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
begin
|
2
|
+
require "vagrant"
|
3
|
+
rescue LoadError
|
4
|
+
raise "The Vagrant Dustcloud plugin must be run within Vagrant."
|
5
|
+
end
|
6
|
+
# This is a sanity check to make sure no one is attempting to install
|
7
|
+
# this into an early Vagrant version.
|
8
|
+
if Vagrant::VERSION < "1.2.0"
|
9
|
+
raise "The Vagrant Dustcloud plugin is only compatible with Vagrant 1.2+"
|
10
|
+
end
|
11
|
+
module VagrantPlugins
|
12
|
+
module Dustcloud
|
13
|
+
class Plugin < Vagrant.plugin("2")
|
14
|
+
name "LUDD DUSTcloud Provisioner"
|
15
|
+
description <<-DESC
|
16
|
+
This plugin installs a provider that allows Vagrant to manage
|
17
|
+
machines in LUDD DUSTcloud.
|
18
|
+
DESC
|
19
|
+
|
20
|
+
config(:dustcloud, :provider) do
|
21
|
+
require_relative "config"
|
22
|
+
Config
|
23
|
+
end
|
24
|
+
|
25
|
+
provider(:dustcloud) do
|
26
|
+
setup_i18n
|
27
|
+
|
28
|
+
require_relative "provider"
|
29
|
+
Provider
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.setup_i18n
|
33
|
+
I18n.load_path << File.expand_path("locales/en.yaml", Dustcloud.source_root)
|
34
|
+
I18n.reload!
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "vagrant"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Dustcloud
|
5
|
+
class Provider < Vagrant.plugin("2", :provider)
|
6
|
+
def initialize(machine)
|
7
|
+
@machine = machine
|
8
|
+
end
|
9
|
+
|
10
|
+
def action(name)
|
11
|
+
# Attempt to get the action method from the Action class if it
|
12
|
+
# exists, otherwise return nil to show that we don't support the
|
13
|
+
# given action.
|
14
|
+
action_method = "action_#{name}"
|
15
|
+
return Action.send(action_method) if Action.respond_to?(action_method)
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def ssh_info
|
20
|
+
# Run a custom action called "read_ssh_info" which does what it
|
21
|
+
# says and puts the resulting SSH info into the `:machine_ssh_info`
|
22
|
+
# key in the environment.
|
23
|
+
env = @machine.action("read_ssh_info", lock: false)
|
24
|
+
env[:machine_ssh_info]
|
25
|
+
end
|
26
|
+
|
27
|
+
def state
|
28
|
+
# Run a custom action we define called "read_state" which does
|
29
|
+
# what it says. It puts the state in the `:machine_state_id`
|
30
|
+
# key in the environment.
|
31
|
+
env = @machine.action("read_state", lock: false)
|
32
|
+
|
33
|
+
state_id = env[:machine_state_id]
|
34
|
+
|
35
|
+
# Get the short and long description
|
36
|
+
short = I18n.t("vagrant_dustcloud.states.short_#{state_id}")
|
37
|
+
long = I18n.t("vagrant_dustcloud.states.long_#{state_id}")
|
38
|
+
|
39
|
+
# Return the MachineState object
|
40
|
+
Vagrant::MachineState.new(state_id, short, long)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_s
|
44
|
+
id = @machine.id.nil? ? "new" : @machine.id
|
45
|
+
"AWS (#{id})"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module VagrantPlugins
|
2
|
+
module Dustcloud
|
3
|
+
module Util
|
4
|
+
class Timer
|
5
|
+
# A basic utility method that times the execution of the given
|
6
|
+
# block and returns it.
|
7
|
+
def self.time
|
8
|
+
start_time = Time.now.to_f
|
9
|
+
yield
|
10
|
+
end_time = Time.now.to_f
|
11
|
+
|
12
|
+
end_time - start_time
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/locales/en.yaml
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
en:
|
2
|
+
vagrant_dustcloud:
|
3
|
+
already_status: |-
|
4
|
+
The machine is already %{status}.
|
5
|
+
launching_instance: |-
|
6
|
+
Launching an instance with the following settings...
|
7
|
+
not_created: |-
|
8
|
+
Instance is not created. Please run `vagrant up` first.
|
9
|
+
ready: |-
|
10
|
+
Machine is booted and ready for use!
|
11
|
+
rsync_not_found_warning: |-
|
12
|
+
Warning! Folder sync disabled because the rsync binary is missing in the %{side}.
|
13
|
+
Make sure rsync is installed and the binary can be found in the PATH.
|
14
|
+
rsync_folder: |-
|
15
|
+
Rsyncing folder: %{hostpath} => %{guestpath}
|
16
|
+
starting: |-
|
17
|
+
Starting the instance...
|
18
|
+
stopping: |-
|
19
|
+
Stopping the instance...
|
20
|
+
terminating: |-
|
21
|
+
Terminating the instance...
|
22
|
+
terminating_failed: |-
|
23
|
+
Failed to terminate the instance
|
24
|
+
terminating_help: |-
|
25
|
+
You may need to use the Cloud Dashboard (https://dust.ludd.ltu.se) or contact the administrators.
|
26
|
+
waiting_for_ready: |-
|
27
|
+
Waiting for instance to become "ready"...
|
28
|
+
waiting_for_ssh: |-
|
29
|
+
Waiting for SSH to become available...
|
30
|
+
will_not_destroy: |-
|
31
|
+
The instance '%{name}' will not be destroyed, since the confirmation
|
32
|
+
was declined.
|
33
|
+
config:
|
34
|
+
token_required: |-
|
35
|
+
An access key ID must be specified via "access_key_id"
|
36
|
+
errors:
|
37
|
+
api_error: |-
|
38
|
+
There was an error talking to Dustcloud. The error message is shown
|
39
|
+
below:
|
40
|
+
%{message}
|
41
|
+
internal_api_error: |-
|
42
|
+
There was an error talking to Dustcloud. The error message is shown
|
43
|
+
below:
|
44
|
+
Error: %{error}
|
45
|
+
Response: %{response}
|
46
|
+
instance_ready_timeout: |-
|
47
|
+
The instance never became "ready" in Dustcloud. The timeout currently
|
48
|
+
set waiting for the instance to become ready is %{timeout} seconds.
|
49
|
+
Please verify that the machine properly boots.
|
50
|
+
states:
|
51
|
+
short_not_created: |-
|
52
|
+
not created
|
53
|
+
long_not_created: |-
|
54
|
+
The Dustcloud instance is not created. Run `vagrant up` to create it.
|
55
|
+
short_shutoff: |-
|
56
|
+
shut off
|
57
|
+
long_shutoff: |-
|
58
|
+
The Dustcloud instance is stopped. Run `vagrant up` to start it.
|
59
|
+
short_build: |-
|
60
|
+
building
|
61
|
+
long_build: |-
|
62
|
+
The Dustcloud instance is building/planning. It will soon start installation.
|
63
|
+
short_installing: |-
|
64
|
+
installing
|
65
|
+
long_installing: |-
|
66
|
+
The Dustcloud instance is currently setting up.
|
67
|
+
short_active: |-
|
68
|
+
running
|
69
|
+
long_active: |-
|
70
|
+
The Dustcloud instance is running. To stop this machine, you can run
|
71
|
+
`vagrant halt`. To destroy the machine, you can run `vagrant destroy`.
|
@@ -0,0 +1,50 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
require "vagrant-dustcloud/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "vagrant-dustcloud"
|
6
|
+
s.version = VagrantPlugins::Dustcloud::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.license = "MIT"
|
9
|
+
s.authors = "Johan Jatko"
|
10
|
+
s.email = "armedguy@ludd.ltu.se"
|
11
|
+
s.homepage = "https://www.ludd.ltu.se"
|
12
|
+
s.summary = "Enables Vagrant to manage LUDD Dustcloud machines."
|
13
|
+
s.description = "Enables Vagrant to manage LUDD Dustcloud machines."
|
14
|
+
|
15
|
+
|
16
|
+
s.add_development_dependency "rake"
|
17
|
+
# rspec 3.4 to mock File
|
18
|
+
s.add_development_dependency "rspec", "~> 3.4"
|
19
|
+
s.add_development_dependency "rspec-its"
|
20
|
+
|
21
|
+
root_path = File.dirname(__FILE__)
|
22
|
+
all_files = Dir.chdir(root_path) { Dir.glob("**/{*,.*}") }
|
23
|
+
all_files.reject! { |file| [".", ".."].include?(File.basename(file)) }
|
24
|
+
gitignore_path = File.join(root_path, ".gitignore")
|
25
|
+
gitignore = File.readlines(gitignore_path)
|
26
|
+
gitignore.map! { |line| line.chomp.strip }
|
27
|
+
gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
|
28
|
+
|
29
|
+
unignored_files = all_files.reject do |file|
|
30
|
+
# Ignore any directories, the gemspec only cares about files
|
31
|
+
next true if File.directory?(file)
|
32
|
+
|
33
|
+
# Ignore any paths that match anything in the gitignore. We do
|
34
|
+
# two tests here:
|
35
|
+
#
|
36
|
+
# - First, test to see if the entire path matches the gitignore.
|
37
|
+
# - Second, match if the basename does, this makes it so that things
|
38
|
+
# like '.DS_Store' will match sub-directories too (same behavior
|
39
|
+
# as git).
|
40
|
+
#
|
41
|
+
gitignore.any? do |ignore|
|
42
|
+
File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
|
43
|
+
File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
s.files = unignored_files
|
48
|
+
s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
|
49
|
+
s.require_path = 'lib'
|
50
|
+
end
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: vagrant-dustcloud
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johan Jatko
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-09-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.4'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec-its
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Enables Vagrant to manage LUDD Dustcloud machines.
|
56
|
+
email: armedguy@ludd.ltu.se
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files: []
|
60
|
+
files:
|
61
|
+
- ".gitignore"
|
62
|
+
- Gemfile
|
63
|
+
- README.md
|
64
|
+
- Rakefile
|
65
|
+
- dummy.box
|
66
|
+
- example_box/README.md
|
67
|
+
- example_box/metadata.json
|
68
|
+
- lib/vagrant-dustcloud.rb
|
69
|
+
- lib/vagrant-dustcloud/action.rb
|
70
|
+
- lib/vagrant-dustcloud/action/connect_dustcloud.rb
|
71
|
+
- lib/vagrant-dustcloud/action/is_created.rb
|
72
|
+
- lib/vagrant-dustcloud/action/is_stopped.rb
|
73
|
+
- lib/vagrant-dustcloud/action/message_already_created.rb
|
74
|
+
- lib/vagrant-dustcloud/action/message_not_created.rb
|
75
|
+
- lib/vagrant-dustcloud/action/message_will_not_destroy.rb
|
76
|
+
- lib/vagrant-dustcloud/action/read_ssh_info.rb
|
77
|
+
- lib/vagrant-dustcloud/action/read_state.rb
|
78
|
+
- lib/vagrant-dustcloud/action/run_instance.rb
|
79
|
+
- lib/vagrant-dustcloud/action/start_instance.rb
|
80
|
+
- lib/vagrant-dustcloud/action/stop_instance.rb
|
81
|
+
- lib/vagrant-dustcloud/action/terminate_instance.rb
|
82
|
+
- lib/vagrant-dustcloud/action/timed_provision.rb
|
83
|
+
- lib/vagrant-dustcloud/action/wait_for_state.rb
|
84
|
+
- lib/vagrant-dustcloud/config.rb
|
85
|
+
- lib/vagrant-dustcloud/errors.rb
|
86
|
+
- lib/vagrant-dustcloud/plugin.rb
|
87
|
+
- lib/vagrant-dustcloud/provider.rb
|
88
|
+
- lib/vagrant-dustcloud/util/timer.rb
|
89
|
+
- lib/vagrant-dustcloud/version.rb
|
90
|
+
- locales/en.yaml
|
91
|
+
- vagrant-dustcloud.gemspec
|
92
|
+
homepage: https://www.ludd.ltu.se
|
93
|
+
licenses:
|
94
|
+
- MIT
|
95
|
+
metadata: {}
|
96
|
+
post_install_message:
|
97
|
+
rdoc_options: []
|
98
|
+
require_paths:
|
99
|
+
- lib
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
requirements: []
|
111
|
+
rubygems_version: 3.1.2
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Enables Vagrant to manage LUDD Dustcloud machines.
|
115
|
+
test_files: []
|