vagrant-openstack-plugin 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b57c6221fd8bcfe94b1be1c952742f10224fc55
4
- data.tar.gz: 6f65f3af923abc32f53ec5d22015cc5cf2fec267
3
+ metadata.gz: 986c84ac3194d14ea6318c89ff6266e26535afa9
4
+ data.tar.gz: d78d410acf7bec163dd902a614b3dedafcbe3101
5
5
  SHA512:
6
- metadata.gz: 13e6a3c80a50ac260f0f2bcbae43c58f9349f5f3533f7ca62dbe7f7bb58d3d9d5212dda6a56741f5feb9704cc4869cc08dff4f27ac4420fcff423a4ab76dae80
7
- data.tar.gz: 3c2bb0c482457bc42836d5f0ae4615e74f1169513d2743d7bace39d471a2b485f3ea38a972a82137fa06282d0505cef572b0987d83c20cc50343d691da68f867
6
+ metadata.gz: 643ff0ffe7ab2c7f9ac797ffc48a6bbb6b32786141e8d4d264f8167820699692c38584feb872b555564beb3fc5b91028910ab35ebb72aca816551e5559773078
7
+ data.tar.gz: b995f34d40199ec3a153cb5d63776b5cca113fd81eac5b6a498742a883cbd3dd129644e7494a293497874237d73da4aea904bd355614d2e7d649df9005f5581b
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ .idea
3
4
  .bundle
4
5
  .config
5
6
  .vagrant
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog for vagrant-openstack-plugin
2
2
 
3
+ ## 0.8.0
4
+
5
+ - Merge pull request #67 from pradels/master [view commit](http://github.com///commit/15f5b5531622376df952bccc0512a6de50d7a92f)
6
+ - Merge pull request #66 from matope/use-execute-to-make-synced_folder [view commit](http://github.com///commit/96f64a846d40e5c7f0355def17189e38895e29f3)
7
+ - Merge pull request #72 from mathuin/fix-handlebox [view commit](http://github.com///commit/3396e33e54d2527d28a70f1487da6221cd2316e2)
8
+ - Merge pull request #64 from bewiwi/reboot [view commit](http://github.com///commit/24bec035508853be871ed8ed73b1d33f15beff76)
9
+ - Merge pull request #63 from bewiwi/status [view commit](http://github.com///commit/79a8c341501461a0d5ef1ce4f11cc0a1810d38f3)
10
+ - Merge pull request #71 from bewiwi/add_openstack_snapshot_commmand [view commit](http://github.com///commit/bf4eedd6eb5e29aefe4c0e156b932b4f4a81e1f5)
11
+ - Merge pull request #73 from detiber/configNetworks [view commit](http://github.com///commit/5e17c5aaeee7bebc4991e440565f2ee4c1b6f191)
12
+ - Set config.networks to [] if unset [view commit](http://github.com///commit/5aad087358792bee0bd1a6a026820b04bb8ca68f)
13
+ - Changed HandleBoxUrl to HandleBox. [view commit](http://github.com///commit/ad7b2acdea81fe6f4b50e4658ecd36762a849f74)
14
+ - Add command snapshot [view commit](http://github.com///commit/2d207ced7e70fe206fa309ed43a8ace3eb86b327)
15
+ - Orchestration support added. [view commit](http://github.com///commit/d4e098db8517d491adfeb826500ac3ec5384d237)
16
+ - Avoid using sudo to make synced_folder if possible [view commit](http://github.com///commit/b5b6205fbc34e95b4dbd9c13f974b728cb27c76e)
17
+ - Add some status messages [view commit](http://github.com///commit/0c9287bc765e074eac104e02d7a64b36bd122034)
18
+ - Modify reload action to be a real reboot [view commit](http://github.com///commit/91f5dc65a781d062d156b912bfd9d4b84db82e44)
19
+
3
20
  ## 0.7.0
4
21
 
5
22
  - Merge pull request #35 from johnbellone/master [view commit](http://github.com///commit/5969261f11585e19348e903eec15617634c3c899)
data/README.md CHANGED
@@ -77,6 +77,12 @@ Vagrant.configure("2") do |config|
77
77
  os.security_groups = ['ssh', 'http'] # optional
78
78
  os.tenant = "YOUR TENANT_NAME" # optional
79
79
  os.floating_ip = "33.33.33.33" # optional (The floating IP to assign for this instance)
80
+
81
+ os.orchestration_stack_name = 'stack01' # optional
82
+ os.orchestration_cfn_template_file = '/tmp/cfn_heat_template.json' # optional
83
+ os.orchestration_cfn_template_parameters = { # optional
84
+ 'NetworkName' => 'net_01'
85
+ }
80
86
  end
81
87
  end
82
88
  ```
@@ -140,6 +146,18 @@ This provider exposes quite a few provider-specific configuration options:
140
146
  * `ssl_verify_peer` - sets the ssl_verify_peer on the underlying excon connection - useful for self signed certs etc.
141
147
  * `floating_ip` - Floating ip. The floating IP to assign for this instance. If
142
148
  set to :auto, then this assigns any available floating IP to the instance.
149
+ * `orchestration_stack_name` - Name for orchestration stack. Mandatory
150
+ parameter when creating new stack. One of parameters for template should be
151
+ set with this parameter.
152
+ * `orchestration_stack_destroy` - If stack created by vagrant should be deleted
153
+ when destroy action is invoked. Default value is `false`.
154
+ * `orchestration_cfn_template` - AWS CloudFormation Template specified as a string.
155
+ * `orchestration_cfn_template_file` - AWS CloudFormation Template file path
156
+ accessible for vagrant.
157
+ * `orchestration_cfn_template_url` - AWS CloudFormation Template URL.
158
+ * `orchestration_cfn_template_parameters` - AWS CloudFormation Template
159
+ parameters specified in ruby hash (take a look at example Vagrantfile).
160
+ This parameter is optional.
143
161
 
144
162
  These can be set like typical provider-specific configuration:
145
163
 
@@ -171,6 +189,13 @@ the remote machine over SSH.
171
189
  This is good enough for all built-in Vagrant provisioners (shell,
172
190
  chef, and puppet) to work!
173
191
 
192
+ ## Command
193
+
194
+ ### Snapshot
195
+ `vagrant openstack snapshot <vmname> -n <snapshotname>`
196
+
197
+ Take snapshot of ***vmname*** with name ***snapshotname***
198
+
174
199
  ## Contributors
175
200
 
176
201
  - [mitchellh](https://github.com/mitchellh)
@@ -16,6 +16,7 @@ module VagrantPlugins
16
16
  if env[:result]
17
17
  b1.use ConnectOpenStack
18
18
  b1.use DeleteServer
19
+ b1.use DeleteOrchestrationStack
19
20
  else
20
21
  b1.use MessageWillNotDestroy
21
22
  end
@@ -86,12 +87,13 @@ module VagrantPlugins
86
87
  # This action is called when `vagrant up` is executed.
87
88
  def self.action_up
88
89
  Vagrant::Action::Builder.new.tap do |b|
89
- b.use HandleBoxUrl
90
+ b.use HandleBox
90
91
  b.use ConfigValidate
91
92
  b.use Call, IsCreated do |env, b1|
92
93
  unless env[:result]
93
94
  b1.use action_prepare_boot
94
95
  b1.use ConnectOpenStack
96
+ b1.use CreateOrchestrationStack
95
97
  b1.use CreateServer
96
98
  else
97
99
  b1.use action_resume
@@ -125,14 +127,12 @@ module VagrantPlugins
125
127
  b.use Call, IsPaused do |env, b1|
126
128
  unless env[:result]
127
129
  b1.use Call, IsSuspended do |env2, b2|
128
- b1.use action_halt unless env2[:result]
130
+ b2.use RebootServer
129
131
  end
130
132
  end
131
133
 
132
- b1.use Call, WaitForState, [:paused, :suspended], 120 do |env2, b2|
133
- if env2[:result]
134
- b2.use action_up
135
- else
134
+ b1.use Call, WaitForState, [:active], 120 do |env2, b2|
135
+ unless env2[:result]
136
136
  b2.use HardRebootServer
137
137
  end
138
138
  end
@@ -198,6 +198,34 @@ module VagrantPlugins
198
198
  end
199
199
  end
200
200
 
201
+ def self.action_take_snapshot
202
+ Vagrant::Action::Builder.new.tap do |b|
203
+ b.use ConfigValidate
204
+ b.use Call, IsCreated do |env, b1|
205
+ if env[:result]
206
+ b1.use ConnectOpenStack
207
+ b1.use Call, IsSnapshoting do |env,b2|
208
+ if env[:result]
209
+ b2.use MessageSnapshotInProgress
210
+ else
211
+ b2.use TakeSnapshot
212
+ end
213
+
214
+ b2.use Call, WaitForTask, [nil], 1200 do |env3, b3|
215
+ if env3[:result]
216
+ b3.use MessageSnapshotDone
217
+ end
218
+ end
219
+
220
+
221
+ end
222
+ else
223
+ b1.use MessageNotCreated
224
+ end
225
+ end
226
+ end
227
+ end
228
+
201
229
  # The autoload farm
202
230
  action_root = Pathname.new(File.expand_path("../action", __FILE__))
203
231
  autoload :ConnectOpenStack, action_root.join("connect_openstack")
@@ -206,12 +234,15 @@ module VagrantPlugins
206
234
  autoload :HardRebootServer, action_root.join("hard_reboot_server")
207
235
  autoload :IsCreated, action_root.join("is_created")
208
236
  autoload :IsPaused, action_root.join("is_paused")
237
+ autoload :IsSnapshoting, action_root.join("is_snapshoting")
209
238
  autoload :IsSuspended, action_root.join("is_suspended")
210
239
  autoload :MessageAlreadyCreated, action_root.join("message_already_created")
211
240
  autoload :MessageAlreadyPaused, action_root.join("message_already_paused")
212
241
  autoload :MessageAlreadySuspended, action_root.join("message_already_suspended")
213
242
  autoload :MessageNotCreated, action_root.join("message_not_created")
214
243
  autoload :MessageNotSuspended, action_root.join("message_not_suspended")
244
+ autoload :MessageSnapshotDone, action_root.join("message_snapshot_done")
245
+ autoload :MessageSnapshotInProgress, action_root.join("message_snapshot_in_progress")
215
246
  autoload :MessageWillNotDestroy, action_root.join("message_will_not_destroy")
216
247
  autoload :MessageServerRunning, action_root.join("message_server_running")
217
248
  autoload :PauseServer, action_root.join("pause_server")
@@ -221,8 +252,12 @@ module VagrantPlugins
221
252
  autoload :ResumeServer, action_root.join("resume_server")
222
253
  autoload :SuspendServer, action_root.join("suspend_server")
223
254
  autoload :SyncFolders, action_root.join("sync_folders")
255
+ autoload :TakeSnapshot, action_root.join("take_snapshot")
224
256
  autoload :WaitForState, action_root.join("wait_for_state")
257
+ autoload :WaitForTask, action_root.join("wait_for_task")
225
258
  autoload :WarnNetworks, action_root.join("warn_networks")
259
+ autoload :CreateOrchestrationStack, action_root.join("create_orchestration_stack")
260
+ autoload :DeleteOrchestrationStack, action_root.join("delete_orchestration_stack")
226
261
  end
227
262
  end
228
263
  end
@@ -29,17 +29,22 @@ module VagrantPlugins
29
29
  :ssl_verify_peer => config.ssl_verify_peer
30
30
  }
31
31
 
32
- @logger.info("Connecting to OpenStack...")
33
- @logger.debug("API connection params: #{connection_options.inspect}")
34
- env[:openstack_compute] = Fog::Compute.new({
35
- :provider => :openstack,
32
+ # Prepare connection parameters for use with fog service
33
+ # initialization (compute, storage, orchestration, ...).
34
+ env[:fog_openstack_params] = {
35
+ :provider => :openstack,
36
36
  :connection_options => connection_options,
37
37
  :openstack_username => username,
38
- :openstack_api_key => api_key,
38
+ :openstack_api_key => api_key,
39
39
  :openstack_auth_url => endpoint,
40
- :openstack_tenant => tenant,
41
- :openstack_region => region
42
- })
40
+ :openstack_tenant => tenant,
41
+ :openstack_region => region
42
+ }
43
+
44
+ @logger.info("Connecting to OpenStack...")
45
+ @logger.debug("API connection params: #{connection_options.inspect}")
46
+ env[:openstack_compute] = Fog::Compute.new(
47
+ env[:fog_openstack_params])
43
48
 
44
49
  if config.networks && !config.networks.empty?
45
50
  env[:openstack_network] = Fog::Network.new({
@@ -0,0 +1,97 @@
1
+ require "fog"
2
+ require "log4r"
3
+
4
+ module VagrantPlugins
5
+ module OpenStack
6
+ module Action
7
+ class CreateOrchestrationStack
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new(
12
+ "vagrant_openstack::action::create_orchestration_stack")
13
+ end
14
+
15
+ def call(env)
16
+ # Get the config.
17
+ config = env[:machine].provider_config
18
+
19
+ # Are we going to handle orchestration stacks?
20
+ if not config.orchestration_stack_name
21
+ return @app.call(env)
22
+ end
23
+
24
+ # Create new fog orchestration service.
25
+ env[:openstack_orchestration] = Fog::Orchestration.new(
26
+ env[:fog_openstack_params])
27
+
28
+ # Check if stack is already created.
29
+ env[:openstack_orchestration].list_stacks.body['stacks'].each do |stack|
30
+ if config.orchestration_stack_name == stack['stack_name']
31
+ return @app.call(env)
32
+ end
33
+ end
34
+
35
+ # To avoid confusion, only one source for orchestration template
36
+ # should be set.
37
+ if [config.orchestration_cfn_template,
38
+ config.orchestration_cfn_template_file,
39
+ config.orchestration_cfn_template_url].count(nil) != 2
40
+ raise Errors::OrchestrationTemplateError,
41
+ :err => 'One source for orchestration template should be specified.'
42
+ end
43
+
44
+ # Prepare parameters for new orchestration stack.
45
+ # TODO: configurable parameters
46
+ stack_params = {
47
+ :disable_rollback => false,
48
+ :timeout_in_minutes => 5,
49
+ }
50
+
51
+ # Set template source.
52
+ if config.orchestration_cfn_template
53
+ stack_params[:template] = config.orchestration_cfn_template
54
+ elsif config.orchestration_cfn_template_file
55
+ if not File.exist?(config.orchestration_cfn_template_file)
56
+ raise Errors::OrchestrationNoTemplateFileError,
57
+ :fname => config.orchestration_cfn_template_file
58
+ end
59
+
60
+ # Load template file content. Newlines can cause parse error of
61
+ # input JSON string.
62
+ stack_params[:template] = ''
63
+ File.open(config.orchestration_cfn_template_file) { |file|
64
+ file.each_line do |line|
65
+ stack_params[:template] << line
66
+ end
67
+ }
68
+ else
69
+ stack_params[:template_url] = config.orchestration_cfn_template_url
70
+ end
71
+
72
+ # Set template parameters.
73
+ stack_params[:parameters] = config.orchestration_cfn_template_parameters
74
+
75
+ # Create new stack.
76
+ env[:ui].info(I18n.t("vagrant_openstack.creating_orchestration_stack"))
77
+ stack = env[:openstack_orchestration].create_stack(
78
+ config.orchestration_stack_name, stack_params)
79
+
80
+ # Write UUID of newly created stack into file for later use (stack removal).
81
+ created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
82
+ message = 'Saving information about created orchestration stack '
83
+ message << "#{config.orchestration_stack_name}, "
84
+ message << "UUID=#{stack.body['stack']['id']} "
85
+ message << "to file #{created_stacks_fname}."
86
+ @logger.info(message)
87
+
88
+ File.open(created_stacks_fname, 'a') do |file|
89
+ file.puts stack.body['stack']['id']
90
+ end
91
+
92
+ @app.call(env)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -49,6 +49,8 @@ module VagrantPlugins
49
49
  unless config.networks
50
50
  if config.network
51
51
  config.networks = [ config.network ]
52
+ else
53
+ config.networks = []
52
54
  end
53
55
  end
54
56
 
@@ -0,0 +1,78 @@
1
+ require "fog"
2
+ require "log4r"
3
+
4
+ module VagrantPlugins
5
+ module OpenStack
6
+ module Action
7
+ class DeleteOrchestrationStack
8
+
9
+ def initialize(app, env)
10
+ @app = app
11
+ @logger = Log4r::Logger.new(
12
+ "vagrant_openstack::action::delete_orchestration_stack")
13
+ end
14
+
15
+ def call(env)
16
+ # Get the config.
17
+ config = env[:machine].provider_config
18
+
19
+ # Load IDs for orchestration stacks created by vagrant and this
20
+ # project.
21
+ created_stacks_fname = env[:machine].data_dir + 'orchestration_stacks'
22
+
23
+ # Return if no action is needed.
24
+ if not config.orchestration_stack_destroy or not File.exist?(created_stacks_fname)
25
+ env[:machine].id = nil
26
+ return @app.call(env)
27
+ end
28
+
29
+ # Create new fog orchestration service.
30
+ env[:openstack_orchestration] = Fog::Orchestration.new(
31
+ env[:fog_openstack_params])
32
+
33
+ # Load IDs of stacks to be deleted.
34
+ available_stacks = env[:openstack_orchestration].list_stacks.body['stacks']
35
+ stacks_to_delete = []
36
+ File.open(created_stacks_fname) { |file|
37
+ file.each_line do |stack_id|
38
+ stack = find_stack(available_stacks, stack_id.chomp!)
39
+ next if not stack
40
+ stacks_to_delete << stack
41
+ end
42
+ }
43
+
44
+ # Delete stacks.
45
+ if stacks_to_delete.length > 0
46
+ env[:ui].info(I18n.t("vagrant_openstack.deleting_orchestration_stacks"))
47
+ end
48
+
49
+ stacks_to_delete.each do |stack|
50
+ @logger.info("Removing orchestration stack #{stack['stack_name']} (#{stack['id']}).")
51
+ env[:openstack_orchestration].delete_stack(
52
+ stack['stack_name'], stack['id'])
53
+
54
+ stacks_from_file.delete(stack)
55
+ end
56
+
57
+ # Delete file holding created stack IDs.
58
+ @logger.info("Deleting file #{created_stacks_fname}.")
59
+ File.delete(created_stacks_fname)
60
+
61
+ env[:machine].id = nil
62
+ @app.call(env)
63
+ end
64
+
65
+ private
66
+
67
+ def find_stack(available_stacks, stack_id)
68
+ available_stacks.each do |stack|
69
+ if stack['id'] == stack_id
70
+ return stack
71
+ end
72
+ end
73
+ false
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -20,7 +20,6 @@ module VagrantPlugins
20
20
  # TODO: Validate the fact that we get a server back from the API.
21
21
  server = env[:openstack_compute].servers.get(id)
22
22
  server.destroy
23
- env[:machine].id = nil
24
23
  end
25
24
 
26
25
  @app.call(env)
@@ -0,0 +1,24 @@
1
+ module VagrantPlugins
2
+ module OpenStack
3
+ module Action
4
+ class IsSnapshoting
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ if env[:machine].id
11
+ infos = env[:openstack_compute].get_server_details(env[:machine].id)
12
+ task = infos.body['server']['OS-EXT-STS:task_state']
13
+ if task == 'image_snapshot' || task == 'image_pending_upload'
14
+ env[:result] = true
15
+ else
16
+ env[:result] = false
17
+ end
18
+ end
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
- module OpenStack
2
+ module OpenStack
3
3
  module Action
4
4
  class MessageAlreadyCreated
5
5
  def initialize(app, env)
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module OpenStack
3
+ module Action
4
+ class MessageSnapshotDone
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t("vagrant_openstack.snapshot_done"))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module VagrantPlugins
2
+ module OpenStack
3
+ module Action
4
+ class MessageSnapshotInProgress
5
+ def initialize(app, env)
6
+ @app = app
7
+ end
8
+
9
+ def call(env)
10
+ env[:ui].info(I18n.t("vagrant_openstack.snapshot_in_progress"))
11
+ @app.call(env)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -37,9 +37,15 @@ module VagrantPlugins
37
37
  :guestpath => guestpath))
38
38
 
39
39
  # Create the guest path
40
- env[:machine].communicate.sudo("mkdir -p '#{guestpath}'")
41
- env[:machine].communicate.sudo(
42
- "chown #{ssh_info[:username]} '#{guestpath}'")
40
+ # Use sudo only when it is necessary
41
+ cmd_mkdir = "mkdir -p '#{guestpath}'"
42
+ cmd_chown = "chown #{ssh_info[:username]} '#{guestpath}'"
43
+ if env[:machine].communicate.execute(cmd_mkdir, :error_check => false) != 0 then
44
+ env[:machine].communicate.sudo(cmd_mkdir)
45
+ end
46
+ if env[:machine].communicate.execute(cmd_chown, :error_check => false) != 0 then
47
+ env[:machine].communicate.sudo(cmd_chown)
48
+ end
43
49
 
44
50
  #collect rsync excludes specified :rsync_excludes=>['path1',...] in synced_folder options
45
51
  excludes = ['.vagrant/', 'Vagrantfile', *Array(data[:rsync_excludes])].uniq
@@ -0,0 +1,26 @@
1
+ require "log4r"
2
+
3
+ module VagrantPlugins
4
+ module OpenStack
5
+ module Action
6
+ # This reboots a running server, if there is one.
7
+ class TakeSnapshot
8
+ def initialize(app, env)
9
+ @app = app
10
+ @logger = Log4r::Logger.new("vagrant_openstack::action::take_snapshot")
11
+ end
12
+
13
+ def call(env)
14
+ if env[:machine].id
15
+ env[:ui].info(I18n.t("vagrant_openstack.snapshoting_server"))
16
+ infos = env[:openstack_compute].get_server_details(env[:machine].id)
17
+ env[:openstack_compute].create_image(env[:machine].id,env[:openstack_snapshot_name] || 'snapshot')
18
+
19
+ end
20
+
21
+ @app.call(env)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ require 'log4r'
3
+ require 'timeout'
4
+
5
+ module VagrantPlugins
6
+ module OpenStack
7
+ module Action
8
+ # This action will wait for a machine to reach a specific state or quit by timeout.
9
+ class WaitForTask
10
+ def initialize(app, env, task, timeout)
11
+ @app = app
12
+ @logger = Log4r::Logger.new('vagrant_openstack::action::wait_for_task')
13
+ @task = Array.new(task).flatten
14
+ @timeout = timeout
15
+ end
16
+
17
+ def call(env)
18
+ env[:result] = true
19
+ task = get_task(env)
20
+
21
+ if @task.include?(task)
22
+ @logger.info("Machine already at task #{ task.to_s }")
23
+ else
24
+ @logger.info("Waiting for machine to reach task...")
25
+ begin
26
+ Timeout.timeout(@timeout) do
27
+ sleep 5 until @task.include?(get_task(env))
28
+ end
29
+ rescue Timeout::Error
30
+ env[:result] = false
31
+ end
32
+
33
+ @app.call(env)
34
+ end
35
+ end
36
+
37
+ def get_task(env)
38
+ infos = env[:openstack_compute].get_server_details(env[:machine].id)
39
+ infos.body['server']['OS-EXT-STS:task_state']
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,70 @@
1
+ require "vagrant"
2
+ require "vagrant/action/builder"
3
+ require "pathname"
4
+
5
+ module VagrantPlugins
6
+ module OpenStack
7
+ module Action
8
+
9
+ class Command < Vagrant.plugin(2, :command)
10
+
11
+ include Vagrant::Action::Builtin
12
+ # include VagrantPlugins::OpenStack::Action
13
+
14
+ def initialize(argv, env)
15
+ super
16
+
17
+ @main_args, @sub_command, @sub_args = split_main_and_subcommand(argv)
18
+
19
+ @subcommands = Vagrant::Registry.new
20
+ @subcommands.register(:snapshot) do
21
+ require_relative 'command/command_snapshot'
22
+ CommandTakeSnapshot
23
+ end
24
+ end
25
+
26
+
27
+
28
+ def execute
29
+ if @main_args.include?("-h") || @main_args.include?("--help")
30
+ # Print the help for all the sub-commands.
31
+ return help
32
+ end
33
+
34
+ # If we reached this far then we must have a subcommand. If not,
35
+ # then we also just print the help and exit.
36
+ command_class = @subcommands.get(@sub_command.to_sym) if @sub_command
37
+ return help if !command_class || !@sub_command
38
+ @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
39
+
40
+ # Initialize and execute the command class
41
+ command_class.new(@sub_args, @env).execute
42
+ end
43
+
44
+ # Prints the help out for this command
45
+ def help
46
+ opts = OptionParser.new do |o|
47
+ o.banner = "Usage: vagrant openstack <command> [<args>]"
48
+ o.separator ""
49
+ o.separator "Available subcommands:"
50
+
51
+ # Add the available subcommands as separators in order to print them
52
+ # out as well.
53
+ keys = []
54
+ @subcommands.each { |key, value| keys << key.to_s }
55
+
56
+ keys.sort.each do |key|
57
+ o.separator " #{key}"
58
+ end
59
+
60
+ o.separator ""
61
+ o.separator "For help on any individual command run `vagrant openstack <command> -h`"
62
+ end
63
+
64
+ @env.ui.info(opts.help, :prefix => false)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,43 @@
1
+ require "vagrant"
2
+ require "vagrant/action/builder"
3
+ require "pathname"
4
+ require "vagrant-openstack-plugin/action"
5
+
6
+
7
+ module VagrantPlugins
8
+ module OpenStack
9
+ module Action
10
+ class CommandTakeSnapshot < Vagrant.plugin("2", :command)
11
+ include Vagrant::Action::Builtin
12
+
13
+ def execute
14
+ options = {:openstack_snapshot_name => 'snapshot'}
15
+ opts = OptionParser.new do |opts|
16
+ opts.banner = "Enters openstack"
17
+ opts.separator ""
18
+ opts.separator "Usage: vagrant openstack snapshot <vmname> -n <snapshotname>"
19
+
20
+
21
+ opts.on( '-n', '--name NAME', 'snapshotname' ) do |name|
22
+ options[:openstack_snapshot_name] = name
23
+ end
24
+
25
+ end
26
+
27
+ # Parse the options
28
+ argv = parse_options(opts)
29
+
30
+ return if !argv
31
+
32
+
33
+ with_target_vms(argv, :reverse => true) do |vm|
34
+ if vm.provider.to_s == VagrantPlugins::OpenStack::Provider.new(nil).to_s
35
+ vm.action(:take_snapshot,options)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -103,6 +103,14 @@ module VagrantPlugins
103
103
  # signed ssl certificate
104
104
  attr_accessor :ssl_verify_peer
105
105
 
106
+ # Heat orchestration configuration parameters.
107
+ attr_accessor :orchestration_stack_name
108
+ attr_accessor :orchestration_stack_destroy
109
+ attr_accessor :orchestration_cfn_template
110
+ attr_accessor :orchestration_cfn_template_file
111
+ attr_accessor :orchestration_cfn_template_url
112
+ attr_accessor :orchestration_cfn_template_parameters
113
+
106
114
  def initialize
107
115
  @api_key = UNSET_VALUE
108
116
  @endpoint = UNSET_VALUE
@@ -125,6 +133,12 @@ module VagrantPlugins
125
133
  @region = UNSET_VALUE
126
134
  @proxy = UNSET_VALUE
127
135
  @ssl_verify_peer = UNSET_VALUE
136
+ @orchestration_stack_name = UNSET_VALUE
137
+ @orchestration_stack_destroy = UNSET_VALUE
138
+ @orchestration_cfn_template = UNSET_VALUE
139
+ @orchestration_cfn_template_file = UNSET_VALUE
140
+ @orchestration_cfn_template_url = UNSET_VALUE
141
+ @orchestration_cfn_template_parameters = UNSET_VALUE
128
142
  end
129
143
 
130
144
  def finalize!
@@ -157,6 +171,13 @@ module VagrantPlugins
157
171
  @region = nil if @region == UNSET_VALUE
158
172
  @proxy = nil if @proxy == UNSET_VALUE
159
173
  @ssl_verify_peer = nil if @ssl_verify_peer == UNSET_VALUE
174
+
175
+ @orchestration_stack_name = nil if @orchestration_stack_name == UNSET_VALUE
176
+ @orchestration_stack_destroy = false if @orchestration_stack_destroy == UNSET_VALUE
177
+ @orchestration_cfn_template = nil if @orchestration_cfn_template == UNSET_VALUE
178
+ @orchestration_cfn_template_file = nil if @orchestration_cfn_template_file == UNSET_VALUE
179
+ @orchestration_cfn_template_url = nil if @orchestration_cfn_template_url == UNSET_VALUE
180
+ @orchestration_cfn_template_parameters = nil if @orchestration_cfn_template_parameters == UNSET_VALUE
160
181
  end
161
182
 
162
183
  def validate(machine)
@@ -34,6 +34,14 @@ module VagrantPlugins
34
34
  class FloatingIPNotFound < VagrantOpenStackError
35
35
  error_key(:floating_ip_not_found)
36
36
  end
37
+
38
+ class OrchestrationTemplateError < VagrantOpenStackError
39
+ error_key(:orchestration_template_error)
40
+ end
41
+
42
+ class OrchestrationNoTemplateFileError < VagrantOpenStackError
43
+ error_key(:orchestration_no_template_file_error)
44
+ end
37
45
  end
38
46
  end
39
47
  end
@@ -12,25 +12,33 @@ end
12
12
 
13
13
  module VagrantPlugins
14
14
  module OpenStack
15
- class Plugin < Vagrant.plugin("2")
16
- name "OpenStack Cloud"
17
- description <<-DESC
15
+ module Action
16
+ class Plugin < Vagrant.plugin("2")
17
+ name "OpenStack Cloud"
18
+ description <<-DESC
18
19
  This plugin enables Vagrant to manage machines in OpenStack Cloud.
19
- DESC
20
+ DESC
20
21
 
21
- config(:openstack, :provider) do
22
- require_relative "config"
23
- Config
24
- end
22
+ config(:openstack, :provider) do
23
+ require_relative "config"
24
+ Config
25
+ end
26
+
27
+ provider(:openstack, parallel: true) do
28
+ # Setup some things
29
+ OpenStack.init_i18n
30
+ OpenStack.init_logging
31
+
32
+ # Load the actual provider
33
+ require_relative "provider"
34
+ Provider
35
+ end
25
36
 
26
- provider(:openstack, parallel: true) do
27
- # Setup some things
28
- OpenStack.init_i18n
29
- OpenStack.init_logging
37
+ command "openstack" do
38
+ require_relative "command"
39
+ Command
40
+ end
30
41
 
31
- # Load the actual provider
32
- require_relative "provider"
33
- Provider
34
42
  end
35
43
  end
36
44
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module OpenStack
3
- VERSION = "0.7.0"
3
+ VERSION = "0.8.0"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -26,6 +26,12 @@ en:
26
26
  The server is ready!
27
27
  rebooting_server: |-
28
28
  This server instance is rebooting!
29
+ snapshoting_server: |-
30
+ This server instance is snapshoting!
31
+ snapshot_done: |-
32
+ Snapshot is ok
33
+ snapshot_in_progress: |-
34
+ Snapshot is in progress
29
35
  resuming_server: |-
30
36
  The server instance has been resumed.
31
37
  rsync_folder: |-
@@ -45,7 +51,10 @@ en:
45
51
  will_not_destroy: |-
46
52
  The instance '%{name}' will not be destroyed, since the confirmation
47
53
  was declined.
48
-
54
+ creating_orchestration_stack: |-
55
+ Creating orchestration stack...
56
+ deleting_orchestration_stacks: |-
57
+ Deleting orchestration stacks...
49
58
  config:
50
59
  api_key_required: |-
51
60
  An API key is required.
@@ -84,6 +93,12 @@ en:
84
93
  floating_ip_not_found: |-
85
94
  A floating IP could not be allocated, as no available floating
86
95
  IPs were found in OpenStack
96
+ orchestration_template_error: |-
97
+ There was an error while reading orchestration template.
98
+ Error: %{err}
99
+ orchestration_no_template_file_error: |-
100
+ Orchestration template file not found (%{fname}).
101
+
87
102
  states:
88
103
  short_active: |-
89
104
  active
@@ -91,6 +106,12 @@ en:
91
106
  The server is up and running. Run `vagrant ssh` to access it.
92
107
  short_build: |-
93
108
  building
109
+ short_suspended: |-
110
+ suspended
111
+ short_paused: |-
112
+ paused
113
+ short_shutoff: |-
114
+ shutdown
94
115
  long_build: |-
95
116
  The server is currently being built. You must wait for this to
96
117
  complete before you can access it. You can delete the server, however,
@@ -12,7 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.summary = "Enables Vagrant to manage machines in OpenStack Cloud."
13
13
  gem.homepage = "http://www.vagrantup.com"
14
14
 
15
- gem.add_runtime_dependency "fog", ">= 1.10.1"
15
+ gem.add_runtime_dependency "fog", ">= 1.16.0"
16
16
 
17
17
  gem.add_development_dependency "rake"
18
18
  gem.add_development_dependency "rspec", "~> 2.13.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrant-openstack-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edmund Haselwanter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-05 00:00:00.000000000 Z
11
+ date: 2014-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.10.1
19
+ version: 1.16.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.10.1
26
+ version: 1.16.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -73,17 +73,22 @@ files:
73
73
  - lib/vagrant-openstack-plugin.rb
74
74
  - lib/vagrant-openstack-plugin/action.rb
75
75
  - lib/vagrant-openstack-plugin/action/connect_openstack.rb
76
+ - lib/vagrant-openstack-plugin/action/create_orchestration_stack.rb
76
77
  - lib/vagrant-openstack-plugin/action/create_server.rb
78
+ - lib/vagrant-openstack-plugin/action/delete_orchestration_stack.rb
77
79
  - lib/vagrant-openstack-plugin/action/delete_server.rb
78
80
  - lib/vagrant-openstack-plugin/action/hard_reboot_server.rb
79
81
  - lib/vagrant-openstack-plugin/action/is_created.rb
80
82
  - lib/vagrant-openstack-plugin/action/is_paused.rb
83
+ - lib/vagrant-openstack-plugin/action/is_snapshoting.rb
81
84
  - lib/vagrant-openstack-plugin/action/is_suspended.rb
82
85
  - lib/vagrant-openstack-plugin/action/message_already_created.rb
83
86
  - lib/vagrant-openstack-plugin/action/message_already_paused.rb
84
87
  - lib/vagrant-openstack-plugin/action/message_already_suspended.rb
85
88
  - lib/vagrant-openstack-plugin/action/message_not_created.rb
86
89
  - lib/vagrant-openstack-plugin/action/message_server_running.rb
90
+ - lib/vagrant-openstack-plugin/action/message_snapshot_done.rb
91
+ - lib/vagrant-openstack-plugin/action/message_snapshot_in_progress.rb
87
92
  - lib/vagrant-openstack-plugin/action/message_will_not_destroy.rb
88
93
  - lib/vagrant-openstack-plugin/action/pause_server.rb
89
94
  - lib/vagrant-openstack-plugin/action/read_ssh_info.rb
@@ -92,8 +97,12 @@ files:
92
97
  - lib/vagrant-openstack-plugin/action/resume_server.rb
93
98
  - lib/vagrant-openstack-plugin/action/suspend_server.rb
94
99
  - lib/vagrant-openstack-plugin/action/sync_folders.rb
100
+ - lib/vagrant-openstack-plugin/action/take_snapshot.rb
95
101
  - lib/vagrant-openstack-plugin/action/wait_for_state.rb
102
+ - lib/vagrant-openstack-plugin/action/wait_for_task.rb
96
103
  - lib/vagrant-openstack-plugin/action/warn_networks.rb
104
+ - lib/vagrant-openstack-plugin/command.rb
105
+ - lib/vagrant-openstack-plugin/command/command_snapshot.rb
97
106
  - lib/vagrant-openstack-plugin/config.rb
98
107
  - lib/vagrant-openstack-plugin/errors.rb
99
108
  - lib/vagrant-openstack-plugin/plugin.rb