vagrant-node 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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