vagrant-node 0.0.2 → 1.0.0

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/README.md CHANGED
@@ -1,4 +1,42 @@
1
1
  vagrant-node
2
2
  ============
3
3
 
4
- Vagrant-node plugin for Vagrant Framework
4
+ This plugin allows you to set a computer with a virtual environment, configured with Vagrant, to be controlled and managed remotely. The remote machine must have installed the controller plugin, [Vagrant-NodeMaster](https://github.com/fjsanpedro/vagrant-nodemaster/tree/master/lib/vagrant-nodemaster).
5
+
6
+ With this plugin installed, the Vagrant environment can perform requests, that you usually can execute locally, but commanded by a remote computer. This service is provided through a REST API that this plugin exposes.
7
+
8
+ This plugin has been developed in the context of the [Catedra SAES](http://www.catedrasaes.org) of the University of Murcia(Spain).
9
+
10
+ ##Installation
11
+ Requires Vagrant 1.2 and libsqlite3-dev
12
+
13
+ ```bash
14
+ $ vagrant plugin install vagrant-node
15
+ ```
16
+
17
+ ##Usage
18
+ In order to start the service provided by *vagrant-node* do:
19
+
20
+ ```bash
21
+ $ vagrant nodeserver start [port]
22
+ ```
23
+
24
+ Port parameter is optional, its default value is 3333. At the first start, you will be prompted to set a password for that node.
25
+
26
+
27
+
28
+ If you want to stop the service just do the following:
29
+
30
+ ```bash
31
+ $ vagrant nodeserver stop
32
+ ```
33
+
34
+ If you want to change the node password just execute:
35
+
36
+ ```bash
37
+ $ vagrant nodeserver passwd
38
+ ```
39
+
40
+
41
+
42
+
@@ -1,4 +1,5 @@
1
1
  require "vagrant-node/version"
2
+ require 'vagrant/plugin'
2
3
 
3
4
  module Vagrant
4
5
  module Node
@@ -0,0 +1,62 @@
1
+ 10
2
+
3
+ dir
4
+ 9519
5
+ svn+ssh://fjlopez@merovingio.inf.um.es/opt/svn-csaesumu/anotaciones/virtualizacion/plugin_vagrant/vagrant-node.v.1.0/lib/vagrant-node/actions
6
+ svn+ssh://fjlopez@merovingio.inf.um.es/opt/svn-csaesumu
7
+
8
+
9
+
10
+ 2013-11-12T10:06:01.121208Z
11
+ 9519
12
+ fjlopez
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+ ba35cbf9-6f3f-4c47-8bc9-f733df4a0683
28
+
29
+ snapshot.rb
30
+ file
31
+ 9673
32
+
33
+
34
+
35
+ 2013-12-12T12:01:25.734270Z
36
+ 902583c2ad2de012ee3561adccd9ea17
37
+ 2013-12-20T12:34:18.314374Z
38
+ 9673
39
+ fjlopez
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+ 8490
62
+
@@ -0,0 +1,310 @@
1
+ require 'pp'
2
+ require "rexml/document"
3
+ require 'rubygems'
4
+ require 'zip/zip'
5
+
6
+
7
+ module Vagrant
8
+ module Node
9
+
10
+ class SnapshotAction
11
+ LIST = :list
12
+ TAKE = :take
13
+ DELETE = :delete
14
+ RESTORE = :restore
15
+ BACKUP = :backup
16
+ ERROR = :error
17
+
18
+ def initialize(app, env)
19
+ @app = app
20
+ end
21
+
22
+ def call(env)
23
+
24
+ #FIXME generate a result code error to this case in order
25
+ #to provide more info to the client
26
+ raise RestException.new(406,"Couldn't perform the operation because machine is not yet created") if env[:machine].state.id==:not_created
27
+ #return @app.call(env) if env[:machine].state.id==:not_created
28
+
29
+ current_driver=env[:machine].provider.driver
30
+
31
+ begin
32
+ current_driver.check_snapshot_stuff
33
+ rescue Exception => e
34
+ case env[:machine].provider_name.to_s
35
+ when "virtualbox" then
36
+ attach_vbox_methods(current_driver)
37
+ end
38
+
39
+ end
40
+
41
+ case env[:machine_action]
42
+ when LIST then
43
+ env[:snapshots_list]=current_driver.list
44
+ when TAKE then
45
+ env[:last_snapshot]=current_driver.take_snapshot(env[:snapshot_name],env[:snapshot_desc])
46
+ when RESTORE then
47
+ env[:restore_result]=current_driver.restore_snapshot(env[:snapshot_id])
48
+ when DELETE then
49
+ env[:delete_result]=current_driver.delete_snapshot(env[:snapshot_id])
50
+ when BACKUP then
51
+ env[:bak_filename]=current_driver.backup_vm(env[:machine].name.to_s,env[:machine].data_dir)
52
+ end
53
+
54
+ @app.call(env)
55
+
56
+ end
57
+
58
+ private
59
+
60
+ def attach_vbox_methods(driver)
61
+
62
+ def driver.check_snapshot_stuff
63
+ return true
64
+ end
65
+
66
+ #FIXME Si no se hace con --pause y la máquina esta running
67
+ #se produce un error y deja a la máquina en estado 'gurumeditating'
68
+ def driver.take_snapshot(name,description=" ")
69
+
70
+ raise RestException.new(400,"Snapshot name can't be emtpy") if name.empty?
71
+
72
+ #Snapshots with the same name are not allowed
73
+ begin
74
+ #if this command doesn't fail means that there is a snapshot with the same name
75
+ execute("snapshot",self.uuid,"showvminfo",name)
76
+ raise RestException.new(400,"There is a snapshot with the same name, please choose another name for the new snapshot")
77
+ rescue Vagrant::Errors::VBoxManageError => e
78
+ #Doing nothing continue with the snapshot creation
79
+ end
80
+
81
+
82
+ #Execute the take command
83
+ if (description)
84
+ execute("snapshot",self.uuid,"take",name,"--description",description,"--pause")
85
+ else
86
+ execute("snapshot",self.uuid,"take",name,"--pause")
87
+ end
88
+
89
+ snapshot = {}
90
+
91
+ #Getting the uuid of the latest snapshot
92
+ execute("snapshot",self.uuid,"list").split("\n").each do |line|
93
+ if line =~ /Name:\s(.*?)\s\(UUID:\s(.*?)\)\s\*$/
94
+ snapshot[:name] = $1
95
+ snapshot[:id] = $2
96
+ end
97
+
98
+ end
99
+
100
+
101
+ #return snapshot
102
+ snapshot
103
+
104
+
105
+ end #driver.take_snapshot
106
+
107
+ def driver.delete_snapshot(snapid)
108
+ raise RestException.new(400,"Snapshot Identifier can't be emtpy") if snapid.empty?
109
+ begin
110
+ execute("snapshot",self.uuid,"delete",snapid)
111
+ return true
112
+ rescue =>e
113
+ if e.message =~ /VBOX_E_OBJECT_NOT_FOUND/
114
+ raise RestException.new(404,"The snapshot identifier provided doesn't exist")
115
+ elsif e.message =~ /NS_ERROR_FAILURE/
116
+ raise RestException.new(500,"Internal VBoxManage Error: can't delete the snapshot, try shutting down the Vm")
117
+ else
118
+ raise RestException.new(500,"Internal VBoxManage Error")
119
+ end
120
+ end
121
+ end
122
+
123
+
124
+
125
+ def driver.backup_vm(vmname,path)
126
+
127
+ zipfilename=nil
128
+ begin
129
+ #Execute the export command
130
+
131
+
132
+ time = Time.now
133
+ basename = "Backup.#{vmname}.#{time.year}.#{time.month}.#{time.day}.#{time.hour}.#{time.min}.#{time.sec}"
134
+ zipfilename = path.to_s + '/'+ basename + '.zip'
135
+
136
+ vmdir = nil
137
+ execute("showvminfo",self.uuid,"--machinereadable").split("\n").each do |line|
138
+ vmdir = File.dirname($1) if line =~ /^CfgFile="(.*?)"$/
139
+ end
140
+
141
+
142
+ Zip::ZipFile.open(zipfilename, Zip::ZipFile::CREATE) do |zipfile|
143
+ Dir[File.join(vmdir, '**', '**')].each do |file|
144
+ zipfile.add(file.sub(vmdir+"/", ''), file)
145
+ end
146
+ end
147
+
148
+ zipfilename
149
+
150
+ rescue => e
151
+ File.delete(zipfilename) if File.exists?(zipfilename)
152
+ return ERROR
153
+ end
154
+
155
+
156
+ end #driver.backup_vm
157
+
158
+
159
+
160
+ # def driver.export_vm(path)
161
+ #
162
+ # begin
163
+ #Execute the export command
164
+ # basename = "Backup.#{Time.now.to_i.to_s}"
165
+ # filename = path + basename
166
+ # execute("export",self.uuid,"--output",filename.to_s+".ovf")
167
+ # zipfilename = filename.to_s + '.zip'
168
+ #
169
+ # files_to_zip = []
170
+ # Dir.chdir(path)
171
+ # Dir.glob(basename+"*") do |file|
172
+ # files_to_zip << file
173
+ # end
174
+ #
175
+ # Zip::ZipFile.open(zipfilename, Zip::ZipFile::CREATE) do |zipfile|
176
+ # files_to_zip.each do |file|
177
+ # zipfile.add(file,file)
178
+ # end
179
+ # end
180
+ #
181
+ #
182
+ # Cleaning files
183
+ # files_to_zip.each do |file|
184
+ # File.delete(file)
185
+ # end
186
+ # return zipfilename
187
+ #
188
+ # rescue => e
189
+ # puts e.message
190
+ # return ERROR
191
+ # end
192
+
193
+
194
+ #end #driver.export_vm
195
+
196
+
197
+ def driver.list
198
+ config = nil
199
+ current_snapshot = nil
200
+
201
+ execute("showvminfo",self.uuid,"--machinereadable").split("\n").each do |line|
202
+ config = $1 if line =~ /^CfgFile="(.*?)"$/
203
+
204
+ end
205
+
206
+ snapshots = []
207
+
208
+ doc = REXML::Document.new File.new(config)
209
+ machine = doc.elements["VirtualBox/Machine"]
210
+
211
+ @current_snapshot = machine.attributes["currentSnapshot"]
212
+
213
+ snapshots = search_snapshot(machine) if @current_snapshot
214
+
215
+
216
+ snapshots
217
+
218
+
219
+ end #driver.list
220
+
221
+ def driver.search_snapshot(path)
222
+
223
+ snapshots = []
224
+ if path
225
+ path.elements.each("Snapshot") { |element|
226
+ snapshot = {}
227
+ original_uuid = element.attributes["uuid"]
228
+ snapshot[:uuid] = original_uuid[1..original_uuid.length-2]
229
+ snapshot[:name] = element.attributes["name"]
230
+ snapshot[:timestamp] = element.attributes["timeStamp"]
231
+
232
+ if element.elements["Description"]
233
+ snapshot[:description] = element.elements["Description"].text
234
+ else
235
+ snapshot[:description] = " "
236
+ end
237
+
238
+ if (original_uuid==@current_snapshot)
239
+ snapshot[:current_state] = true
240
+ else
241
+ snapshot[:current_state] = false
242
+ end
243
+
244
+ snapshot[:snapshots] = search_snapshot(element.elements["Snapshots"])
245
+
246
+ snapshots << snapshot
247
+ }
248
+ end #driver.search_snapshot(path)
249
+
250
+ #return snapshot array
251
+ snapshots
252
+
253
+ end
254
+
255
+ #snapipd could be the snapshot uuid or its name
256
+ def driver.restore_snapshot(snapid)
257
+
258
+ snapshots = []
259
+
260
+ begin
261
+
262
+ result = execute("snapshot",self.uuid,"restore",snapid)
263
+
264
+ if result =~ /^Restoring snapshot\s(.*?)$/
265
+ snapshots << $1
266
+ end
267
+
268
+ #return snapshot array
269
+ snapshots
270
+
271
+ rescue Vagrant::Errors::VBoxManageError => e
272
+ return snapshots if e.message=~ /Could not find a snapshot named/
273
+ end
274
+ end
275
+
276
+ end # attach_vbox_methods(driver)
277
+
278
+
279
+ end
280
+
281
+ end
282
+ end
283
+
284
+ # def driver.list
285
+ # puts "LISTING SNAPSHOT"
286
+ # begin
287
+ # snapshots = []
288
+ # puts "UUID #{self.uuid}"
289
+ # execute("snapshot",self.uuid,"list").split("\n").each do |line|
290
+ # snapshot = {}
291
+ #
292
+ # if line =~ /Name:\s(.*?)\s\(UUID:\s(.*?)\)$/
293
+ # snapshot[:name] = $1
294
+ # snapshot[:id] = $2
295
+ # snapshot[:current_state] = false
296
+ # elsif line =~ /Name:\s(.*?)\s\(UUID:\s(.*?)\)\s\*$/
297
+ # snapshot[:name] = $1
298
+ # snapshot[:id] = $2
299
+ # snapshot[:current_state] = true
300
+ # end
301
+ # snapshots.push(snapshot)
302
+ # end
303
+ # rescue Exception => e
304
+ # puts e.message
305
+ # end
306
+ #
307
+ # puts snapshots
308
+ # return snapshots
309
+ # end
310
+
@@ -1,6 +1,6 @@
1
1
  require 'pp'
2
2
  require "rexml/document"
3
- #require 'rubygems'
3
+ require 'rubygems'
4
4
  require 'zip/zip'
5
5
 
6
6
 
@@ -10,6 +10,7 @@ module Vagrant
10
10
  class SnapshotAction
11
11
  LIST = :list
12
12
  TAKE = :take
13
+ DELETE = :delete
13
14
  RESTORE = :restore
14
15
  BACKUP = :backup
15
16
  ERROR = :error
@@ -22,7 +23,8 @@ module Vagrant
22
23
 
23
24
  #FIXME generate a result code error to this case in order
24
25
  #to provide more info to the client
25
- return @app.call(env) if env[:machine].state.id==:not_created
26
+ raise RestException.new(406,"Couldn't perform the operation because machine is not yet created") if env[:machine].state.id==:not_created
27
+ #return @app.call(env) if env[:machine].state.id==:not_created
26
28
 
27
29
  current_driver=env[:machine].provider.driver
28
30
 
@@ -41,9 +43,10 @@ module Vagrant
41
43
  env[:snapshots_list]=current_driver.list
42
44
  when TAKE then
43
45
  env[:last_snapshot]=current_driver.take_snapshot(env[:snapshot_name],env[:snapshot_desc])
44
- when RESTORE then
45
-
46
+ when RESTORE then
46
47
  env[:restore_result]=current_driver.restore_snapshot(env[:snapshot_id])
48
+ when DELETE then
49
+ env[:delete_result]=current_driver.delete_snapshot(env[:snapshot_id])
47
50
  when BACKUP then
48
51
  env[:bak_filename]=current_driver.backup_vm(env[:machine].name.to_s,env[:machine].data_dir)
49
52
  end
@@ -63,38 +66,61 @@ module Vagrant
63
66
  #FIXME Si no se hace con --pause y la máquina esta running
64
67
  #se produce un error y deja a la máquina en estado 'gurumeditating'
65
68
  def driver.take_snapshot(name,description=" ")
66
-
69
+
70
+ raise RestException.new(400,"Snapshot name can't be emtpy") if name.empty?
71
+
72
+ #Snapshots with the same name are not allowed
67
73
  begin
68
- #Execute the take command
69
- if (description)
70
- execute("snapshot",self.uuid,"take",name,"--description",description,"--pause")
71
- else
72
- execute("snapshot",self.uuid,"take",name,"--pause")
73
- end
74
+ #if this command doesn't fail means that there is a snapshot with the same name
75
+ execute("snapshot",self.uuid,"showvminfo",name)
76
+ raise RestException.new(400,"There is a snapshot with the same name, please choose another name for the new snapshot")
77
+ rescue Vagrant::Errors::VBoxManageError => e
78
+ #Doing nothing continue with the snapshot creation
79
+ end
80
+
81
+
82
+ #Execute the take command
83
+ if (description)
84
+ execute("snapshot",self.uuid,"take",name,"--description",description,"--pause")
85
+ else
86
+ execute("snapshot",self.uuid,"take",name,"--pause")
87
+ end
74
88
 
75
- snapshot = {}
76
- #Getting the uuid of the latest snapshot
77
- execute("snapshot",self.uuid,"list").split("\n").each do |line|
78
-
79
- if line =~ /Name:\s(.*?)\s\(UUID:\s(.*?)\)\s\*$/
80
- snapshot[:name] = $1
81
- snapshot[:id] = $2
82
- end
83
-
89
+ snapshot = {}
90
+
91
+ #Getting the uuid of the latest snapshot
92
+ execute("snapshot",self.uuid,"list").split("\n").each do |line|
93
+ if line =~ /Name:\s(.*?)\s\(UUID:\s(.*?)\)\s\*$/
94
+ snapshot[:name] = $1
95
+ snapshot[:id] = $2
84
96
  end
85
-
86
- #return snapshot
87
- snapshot
88
-
89
-
90
- rescue => e
91
- puts e.message
92
- return nil
97
+
93
98
  end
99
+
100
+
101
+ #return snapshot
102
+ snapshot
94
103
 
95
104
 
96
105
  end #driver.take_snapshot
97
106
 
107
+ def driver.delete_snapshot(snapid)
108
+ raise RestException.new(400,"Snapshot Identifier can't be emtpy") if snapid.empty?
109
+ begin
110
+ execute("snapshot",self.uuid,"delete",snapid)
111
+ return true
112
+ rescue =>e
113
+ if e.message =~ /VBOX_E_OBJECT_NOT_FOUND/
114
+ raise RestException.new(404,"The snapshot identifier provided doesn't exist")
115
+ elsif e.message =~ /NS_ERROR_FAILURE/
116
+ raise RestException.new(500,"Internal VBoxManage Error: can't delete the snapshot, try shutting down the Vm")
117
+ else
118
+ raise RestException.new(500,"Internal VBoxManage Error")
119
+ end
120
+ end
121
+ end
122
+
123
+
98
124
 
99
125
  def driver.backup_vm(vmname,path)
100
126
 
@@ -198,8 +224,8 @@ module Vagrant
198
224
  if path
199
225
  path.elements.each("Snapshot") { |element|
200
226
  snapshot = {}
201
-
202
- snapshot[:uuid] = element.attributes["uuid"]
227
+ original_uuid = element.attributes["uuid"]
228
+ snapshot[:uuid] = original_uuid[1..original_uuid.length-2]
203
229
  snapshot[:name] = element.attributes["name"]
204
230
  snapshot[:timestamp] = element.attributes["timeStamp"]
205
231
 
@@ -209,8 +235,7 @@ module Vagrant
209
235
  snapshot[:description] = " "
210
236
  end
211
237
 
212
- if (snapshot[:uuid]==@current_snapshot)
213
-
238
+ if (original_uuid==@current_snapshot)
214
239
  snapshot[:current_state] = true
215
240
  else
216
241
  snapshot[:current_state] = false