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.
@@ -0,0 +1,284 @@
1
+ require 'vagrant'
2
+ require 'ruby_parser'
3
+ require 'ruby2ruby'
4
+ require 'vagrant-node/exceptions.rb'
5
+
6
+ module Vagrant
7
+ module Node
8
+ class ConfigManager
9
+ attr_accessor :config_global,:config_warnings,:config_errors,:config_sexp
10
+ def initialize(spath_config_file)
11
+ @config_file_path = spath_config_file
12
+ config_loader = Config::Loader.new(Config::VERSIONS, Config::VERSIONS_ORDER)
13
+ config_loader.set(:conffile, File.expand_path(@config_file_path))
14
+ @config_global,@config_warnings, @config_errors = config_loader.load([:confile])
15
+
16
+ config_content = File.read(@config_file_path)
17
+
18
+ @config_sexp = RubyParser.new.parse(config_content)
19
+
20
+ #If config file is in the default style convert it to a block one
21
+ convert_default_to_block
22
+
23
+ end
24
+
25
+
26
+ def extract_vms_sexp
27
+ raise RestException.new(406,"Config File has no virtual machine configured") if (@config_sexp.nil? ||
28
+ @config_sexp.empty? ||
29
+ @config_sexp[VM_INDEX_START].nil?)
30
+
31
+
32
+ if @config_sexp[VM_INDEX_START].node_type==:block
33
+
34
+ if (@config_sexp[VM_INDEX_START].find_nodes(:iter).empty?)
35
+ #One machine with default style
36
+ return default_to_block
37
+
38
+ else
39
+ #Several machines configured
40
+ return @config_sexp[VM_INDEX_START].find_nodes(:iter)
41
+ end
42
+
43
+ else
44
+ #Only one machine configured
45
+ return [@config_sexp[VM_INDEX_START]]
46
+ end
47
+
48
+ end
49
+
50
+ def delete_vm (vm_name)
51
+
52
+
53
+ if !@config_sexp[VM_INDEX_START].nil?
54
+ #Este caso se presenta cuando existe más de una máquina virtual
55
+ #O bien cuando la máquina es de tipo default
56
+ if @config_sexp[VM_INDEX_START].node_type==:block
57
+
58
+ if (@config_sexp[VM_INDEX_START].find_nodes(:iter).empty? && vm_name.to_sym==:default)
59
+ #Una única máquina configurada y no como bloque
60
+ @config_sexp.delete_at(VM_INDEX_START)
61
+ save
62
+ return true
63
+ else
64
+ #Entorno multi vm
65
+ @config_sexp[VM_INDEX_START].each_sexp do |vm|
66
+ vm.find_nodes(:call).first.find_nodes(:lit).each do |node|
67
+ if node.value === vm_name.to_sym
68
+ @config_sexp[VM_INDEX_START].delete(vm)
69
+ save
70
+ return true
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ else
77
+ #Este caso se produce cuando hay unicamente
78
+ #una maquina virtual configurada. En este caso
79
+ #@config_sexp[VM_INDEX_START] contiene la definicion
80
+ #de la maquina directamente
81
+ node=@config_sexp[VM_INDEX_START].find_nodes(:call).first.find_node(:lit)
82
+ if node.value === vm_name.to_sym
83
+ @config_sexp.delete_at(VM_INDEX_START)
84
+ save
85
+ return true
86
+ end
87
+
88
+ end
89
+ end
90
+
91
+ raise RestException.new(404,"Virtual Machine #{vm_name} not found")
92
+
93
+
94
+ end
95
+
96
+
97
+ def get_vm_names
98
+
99
+ raise RestException.new(406,"No virtual machine configured") if @config_sexp[VM_INDEX_START].nil?
100
+
101
+ names = []
102
+ if @config_sexp[VM_INDEX_START].node_type==:block
103
+ #Entorno con una maquina configurada fuera de bloque
104
+ if (@config_sexp[VM_INDEX_START].find_nodes(:iter).empty?)
105
+ names.push(:default)
106
+ else
107
+ #Entorno multi vm
108
+ @config_sexp[VM_INDEX_START].each_sexp do |vm|
109
+ vm.find_nodes(:call).first.find_nodes(:lit).each do |node|
110
+ names.push(node.value)
111
+ end
112
+ end
113
+ end
114
+
115
+ else
116
+ #Este caso se produce cuando hay unicamente
117
+ #una maquina virtual configurada. En este caso
118
+ #@config_sexp[VM_INDEX_START] contiene la definicion
119
+ #de la maquina directamente
120
+ node=@config_sexp[VM_INDEX_START].find_nodes(:call).first.find_node(:lit)
121
+ names.push(node.value)
122
+
123
+ end
124
+
125
+ names
126
+ end
127
+
128
+
129
+ #FIXME REVISAR PORQUE CUANDO QUEDA UNA ÚNICA máquina en un entorno
130
+ #multi vm el fichero cambia
131
+ def rename_vm(old_name,new_name)
132
+ machines = extract_vms_sexp
133
+
134
+ machines.each do |machine|
135
+ machine.find_nodes(:call).first.find_nodes(:lit).each do |node|
136
+ node[1] = new_name.to_sym if (node.value == old_name)
137
+ end
138
+ end
139
+
140
+ end
141
+
142
+ def insert_vms_sexp(vms_sexp)
143
+ raise RestException.new(406,"Invalid configuration file supplied") if vms_sexp.nil? || vms_sexp.empty?
144
+
145
+ if !@config_sexp[VM_INDEX_START].nil?
146
+ # If @config_sexp[VM_INDEX_START] isn't nil could mean three things:
147
+ # -- There is machine configure in with a default style
148
+ # -- There are some machines inserted inside a block
149
+ # -- There is only one machine and it is stored at @config_sexp[VM_INDEX_START]
150
+ if @config_sexp[VM_INDEX_START].node_type==:block
151
+ # If node is a block we could have the first two options
152
+ if (@config_sexp[VM_INDEX_START].find_nodes(:iter).empty?)
153
+ # This case match the first option, so the steps to perdorm are the following:
154
+ # -- Create a block node
155
+ new_block = s(:block)
156
+ # -- Convert the current machine to a block style and insert into the block
157
+ new_block.add(default_to_block)
158
+ # -- Insert the new vms
159
+ new_block.add(vms_sexp)
160
+
161
+
162
+ @config_sexp.delete_at(VM_INDEX_START)
163
+
164
+ @config_sexp[VM_INDEX_START] = new_block
165
+
166
+
167
+ else
168
+ # This case means that there are some machines inserted inside a block
169
+ # we only have to add thems
170
+ #FIXME FALTA COMPREOBAR SI HACE FALTA RENOMBRAR
171
+ @config_sexp[VM_INDEX_START].add(vms_sexp)
172
+ end
173
+
174
+ else
175
+ #There is only one machine stored, we can store it at @config_sexp[VM_INDEX_START]
176
+ new_block = s(:block)
177
+ new_block.add(extract_vms_sexp)
178
+ new_block.add(vms_sexp)
179
+ @config_sexp.delete_at(VM_INDEX_START)
180
+ @config_sexp[VM_INDEX_START] = new_block
181
+
182
+
183
+ end
184
+ else
185
+ #If @config_sexp[VM_INDEX_START] is nil means that there isn't any
186
+ #machine configured
187
+ #In order to proceed correctly we have to check if there are one or more
188
+ #vms to be inserted:
189
+ # -- If there is only one machine to be inserted is must be stored in
190
+ # @config_sexp[VM_INDEX_START] directly
191
+ # -- If there are two ore more vms to be inserted they have to be inserted inside
192
+ # a block in @config_sexp[VM_INDEX_START]
193
+
194
+
195
+ if (vms_sexp.length>1)
196
+ new_block = s(:block)
197
+ new_block.add(vms_sexp)
198
+ @config_sexp[VM_INDEX_START] = new_block
199
+ else
200
+ @config_sexp[VM_INDEX_START] = vms_sexp.first
201
+ end
202
+
203
+ end
204
+
205
+ # Saving the result to disk
206
+ save
207
+
208
+ true
209
+
210
+ end
211
+
212
+ #Ruby2Ruby modify the parameter, so a deep cloned copy is passed
213
+ def config_content
214
+ begin
215
+ Ruby2Ruby.new.process(@config_sexp.dclone)
216
+ rescue => e
217
+ raise RestException.new(406,"There was an error processing the config file, check if there is any error")
218
+ end
219
+ end
220
+
221
+ def save
222
+ #Processing the content first. If there is any error
223
+ #the file wont'be modified
224
+ content= config_content
225
+ f = File.open(@config_file_path, "w")
226
+ f.write(content)
227
+ f.write("\n")
228
+ f.close
229
+ end
230
+
231
+ private
232
+ VM_INDEX_START = 3
233
+ DEFAULT_BLOCK_NAME = :default_config
234
+
235
+
236
+
237
+ def rename_block_to_default(exp)
238
+ exp.each_sexp do |node|
239
+ rename_block_to_default(node)
240
+ # pp node.node_type
241
+ if (node.node_type == :lvar)
242
+ node[1]=DEFAULT_BLOCK_NAME
243
+ end
244
+ end
245
+ end
246
+
247
+ #Process a default virtual machine and produces
248
+ #a block with the vm configuration
249
+ def default_to_block
250
+
251
+
252
+ #Getting the main block name
253
+ mblock_name = @config_sexp[2].value.to_s
254
+
255
+ rename_block_to_default(@config_sexp[VM_INDEX_START])
256
+
257
+ result= RubyParser.new.parse(
258
+ "Vagrant.configure('2') do |#{mblock_name}|"+
259
+ "#{mblock_name}.vm.define(:default) do |#{DEFAULT_BLOCK_NAME.to_s}|\n"+
260
+ Ruby2Ruby.new.process(@config_sexp[VM_INDEX_START].dclone)+
261
+ "end\nend"
262
+ )
263
+
264
+
265
+
266
+ return [result[VM_INDEX_START]]
267
+ end
268
+
269
+ def convert_default_to_block
270
+ if (@config_sexp[VM_INDEX_START].node_type==:block &&
271
+ @config_sexp[VM_INDEX_START].find_nodes(:iter).empty?)
272
+ new_block = s(:block)
273
+ new_block.add(default_to_block)
274
+
275
+ @config_sexp.delete_at(VM_INDEX_START)
276
+ @config_sexp[VM_INDEX_START] = new_block
277
+ end
278
+ end
279
+
280
+ end
281
+
282
+ end
283
+ end
284
+
@@ -1,5 +1,5 @@
1
1
  require 'sqlite3'
2
-
2
+ require 'digest/md5'
3
3
  module Vagrant
4
4
  module Node
5
5
  module DB
@@ -27,28 +27,145 @@ module Vagrant
27
27
  sql="UPDATE #{BACKUP_TABLE_NAME} SET #{BACKUP_STATUS_COLUMN} = ? WHERE #{BACKUP_DATE_COLUMN}= ? AND #{BACKUP_VM_NAME_COLUMN}= ?"
28
28
  @db.execute(sql,status,date,vmname)
29
29
  end
30
-
30
+
31
+ def node_password_set?
32
+ sql="SELECT Count(*) FROM #{PASSWORD_TABLE};"
33
+
34
+ return @db.execute(sql).first[0]!=0
35
+ #return true
36
+
37
+ end
38
+
39
+ def node_check_password?(old_password)
40
+ sql="SELECT #{PASSWORD_COLUMN} FROM #{PASSWORD_TABLE} LIMIT 1;"
41
+ stored_pwd=@db.execute(sql)
42
+
43
+ return (stored_pwd.length!=0 && (stored_pwd.first[0]==Digest::MD5.hexdigest(old_password)))
44
+ #return true
45
+ end
46
+
47
+ def node_password
48
+ sql="SELECT #{PASSWORD_COLUMN} FROM #{PASSWORD_TABLE} LIMIT 1;"
49
+ stored_pwd=@db.execute(sql)
50
+ stored_pwd.first[0]
51
+ end
52
+
53
+ def node_password_set(new_password,raw=false)
54
+ if node_password_set? || !node_default_password_set?
55
+ sql="UPDATE #{PASSWORD_TABLE} SET #{PASSWORD_COLUMN} = ? "
56
+ else
57
+ sql="INSERT INTO #{PASSWORD_TABLE} VALUES (?)"
58
+ end
59
+
60
+ @db.execute(sql,
61
+ ((raw)? new_password:
62
+ Digest::MD5.hexdigest(new_password)))
63
+
64
+ end
65
+
66
+ def node_default_password_set?
67
+ return node_password == DEFAULT_NODE_PASSWORD
68
+ end
69
+
70
+
71
+ def create_queued_process(id)
72
+ sql="INSERT INTO #{OPERATION_QUEUE_TABLE_NAME} VALUES (?, ?, ?, ?, ?)"
73
+ @db.execute(sql,id,Time.now.strftime("%Y-%m-%d") ,Time.now.to_i,PROCESS_IN_PROGRESS,"")
74
+ end
75
+
76
+ def set_queued_process_result(id,result)
77
+ sql="UPDATE #{OPERATION_QUEUE_TABLE_NAME} SET #{OPERATION_STATUS_COLUMN} = ?,#{OPERATION_RESULT_COLUMN} = ? WHERE #{OPERATION_ID_COLUMN}= ?"
78
+ @db.execute(sql,PROCESS_SUCCESS,result,id)
79
+ end
80
+
81
+ def set_queued_process_error(id,exception)
82
+ sql="UPDATE #{OPERATION_QUEUE_TABLE_NAME} SET #{OPERATION_STATUS_COLUMN} = ?,#{OPERATION_RESULT_COLUMN} = ? WHERE #{OPERATION_ID_COLUMN}= ?"
83
+ @db.execute(sql,PROCESS_ERROR,exception.message,id)
84
+ end
85
+
86
+ def get_queued_process_result(id)
87
+ sql="SELECT #{OPERATION_STATUS_COLUMN},#{OPERATION_RESULT_COLUMN} FROM #{OPERATION_QUEUE_TABLE_NAME} WHERE #{OPERATION_ID_COLUMN}= ?;"
88
+ #sql="SELECT * FROM #{OPERATION_QUEUE_TABLE_NAME};"
89
+ @db.execute(sql,id)
90
+ end
91
+
92
+ def get_queued_last
93
+ sql="SELECT #{OPERATION_STATUS_COLUMN},#{OPERATION_RESULT_COLUMN} FROM #{OPERATION_QUEUE_TABLE_NAME};"
94
+ @db.execute(sql)
95
+ end
96
+
97
+
98
+ def remove_queued_processes
99
+ sql="DELETE FROM #{OPERATION_QUEUE_TABLE_NAME}"
100
+ @db.execute(sql)
101
+ end
102
+
31
103
 
32
104
  private
33
105
 
106
+ PROCESS_IN_PROGRESS = 100;
107
+ PROCESS_SUCCESS = 200;
108
+ PROCESS_ERROR = 500;
109
+
34
110
  BACKUP_TABLE_NAME='node_table'
35
111
  BACKUP_DATE_COLUMN = 'date'
36
112
  BACKUP_VM_NAME_COLUMN = 'vm_name'
37
113
  BACKUP_STATUS_COLUMN = 'backup_status'
114
+ PASSWORD_TABLE = 'node_password_table'
115
+ PASSWORD_COLUMN = 'node_password'
116
+ DEFAULT_NODE_PASSWORD = 'catedrasaesumu'
117
+
118
+ OPERATION_QUEUE_TABLE_NAME='operation_queue_table'
119
+ OPERATION_CMD_COLUMN = 'operation_cmd'
120
+ OPERATION_STATUS_COLUMN = 'operation_status'
121
+ OPERATION_RESULT_COLUMN = 'operation_result'
122
+ OPERATION_ID_COLUMN = 'operation_id'
123
+ OPERATION_DATE_COLUMN = 'operation_date'
124
+ OPERATION_TIME_COLUMN = 'operation_time'
38
125
 
39
126
  def check_database(data_dir)
40
127
  #Creates and/or open the database
41
128
 
42
129
  db = SQLite3::Database.new( data_dir.to_s + "/node.db" )
130
+ #Trying to avoid the sqlite3::busyexception
131
+ db.busy_timeout=100;
43
132
 
44
133
  if db.execute("SELECT name FROM sqlite_master
45
134
  WHERE type='table' AND name='#{BACKUP_TABLE_NAME}';").length==0
46
135
  db.execute( "create table '#{BACKUP_TABLE_NAME}' (#{BACKUP_DATE_COLUMN} TEXT NOT NULL,
47
136
  #{BACKUP_VM_NAME_COLUMN} TEXT PRIMARY_KEY,
48
137
  #{BACKUP_STATUS_COLUMN} TEXT NOT NULL);" )
138
+
139
+
140
+
141
+
49
142
  end
50
143
 
51
- #return db
144
+
145
+ if db.execute("SELECT name FROM sqlite_master
146
+ WHERE type='table' AND name='#{PASSWORD_TABLE}';").length==0
147
+ db.execute("create table '#{PASSWORD_TABLE}' (#{PASSWORD_COLUMN} TEXT NOT NULL);" )
148
+ db.execute("INSERT INTO #{PASSWORD_TABLE} VALUES (\"#{DEFAULT_NODE_PASSWORD}\");");
149
+ end
150
+
151
+ if db.execute("SELECT name FROM sqlite_master
152
+ WHERE type='table' AND name='#{OPERATION_QUEUE_TABLE_NAME}';").length==0
153
+
154
+ # db.execute( "create table '#{OPERATION_QUEUE_TABLE_NAME}' (#{OPERATION_ID_COLUMN} INTEGER PRIMARY_KEY,
155
+ # #{OPERATION_CMD_COLUMN} TEXT NOT NULL,
156
+ # #{OPERATION_DATE_COLUMN} TEXT NOT NULL,
157
+ # #{OPERATION_TIME_COLUMN} INTEGER NOT NULL,
158
+ # #{OPERATION_STATUS_COLUMN} TEXT NOT NULL,
159
+ # #{OPERATION_RESULT_COLUMN} TEXT NOT NULL);" )
160
+ db.execute( "create table '#{OPERATION_QUEUE_TABLE_NAME}' (#{OPERATION_ID_COLUMN} INTEGER PRIMARY_KEY,
161
+ #{OPERATION_DATE_COLUMN} TEXT NOT NULL,
162
+ #{OPERATION_TIME_COLUMN} INTEGER NOT NULL,
163
+ #{OPERATION_STATUS_COLUMN} INTEGER NOT NULL,
164
+ #{OPERATION_RESULT_COLUMN} TEXT NOT NULL);" )
165
+
166
+ end
167
+
168
+
52
169
  db
53
170
 
54
171
  end
@@ -0,0 +1,87 @@
1
+
2
+ require 'vagrant'
3
+
4
+ module Vagrant
5
+ module Node
6
+
7
+ class RestException < StandardError
8
+ def initialize(code,msg)
9
+ super(msg)
10
+ @code = code
11
+ end
12
+ def code
13
+ @code
14
+ end
15
+ end
16
+
17
+ class ExceptionMutator < RestException
18
+ include Vagrant::Errors
19
+ def initialize(exception)
20
+ if (exception.is_a?(Vagrant::Errors::VagrantError))
21
+ puts exception.class
22
+ case exception
23
+ when BaseVMNotFound,
24
+ BoxNotFound,
25
+ BoxSpecifiedDoesntExist,
26
+ MachineNotFound,
27
+ NetworkNotFound,
28
+ ProviderNotFound,
29
+ VMNotFoundError,
30
+ VagrantfileExistsError
31
+ super(404,exception.message)
32
+ when BoxNotSpecified,
33
+ CLIInvalidOptions,
34
+ CLIInvalidUsage,
35
+ DestroyRequiresForce
36
+ super(400,exception.message)
37
+ when ConfigInvalid,
38
+ NameError,
39
+ # ConfigValidationFailed,
40
+ # DeprecationError,
41
+ DownloaderFileDoesntExist,
42
+ BoxProviderDoesntMatch,
43
+ #BoxDownloadUnknownType,
44
+ BoxAlreadyExists,
45
+ ActiveMachineWithDifferentProvider,
46
+ BoxUnpackageFailure,
47
+ BoxUpgradeRequired,
48
+ BoxVerificationFailed,
49
+ VMImportFailure
50
+ super(406,exception.message)
51
+ else
52
+ super(500,exception.message)
53
+ end
54
+
55
+ else
56
+ super(500,exception.message)
57
+ end
58
+
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+
65
+
66
+ # Otras que por ahora no veo la necesidad de incluirlas
67
+ # , , , ,
68
+ # , , DotfileIsDirectory, DotfileUpgradeJSONError, ,
69
+ # DownloaderHTTPConnectReset, DownloaderHTTPConnectTimeout, DownloaderHTTPSocketError, DownloaderHTTPStatusError,
70
+ # EnvironmentLockedError, EnvironmentNonExistentCWD, ForwardPortAutolistEmpty, ForwardPortCollision,
71
+ # ForwardPortCollisionResume, GemCommandInBundler, HomeDirectoryMigrationFailed, HomeDirectoryNotAccessible,
72
+ # LocalDataDirectoryNotAccessible, MachineGuestNotReady, , MultiVMEnvironmentRequired, MultiVMTargetRequired,
73
+ # NFSHostRequired, NFSNoHostNetwork, NFSNotSupported, NetworkAdapterCollision, NetworkCollision,
74
+ # NetworkDHCPAlreadyAttached, NetworkNoAdapters, , NoEnvironmentError,
75
+ # PackageIncludeMissing, PackageOutputDirectory, PackageOutputExists, PackageRequiresDirectory,
76
+ # PersistDotfileExists, PluginLoadError, , SCPPermissionDenied, SCPUnavailable, SSHAuthenticationFailed
77
+ # , SSHConnectionRefused, SSHConnectionTimeout, SSHDisconnected, SSHHostDown, SSHKeyBadPermissions
78
+ # , SSHKeyTypeNotSupported, SSHNotReady, SSHPortNotDetected, SSHUnavailable
79
+ # , SSHUnavailableWindows, SharedFolderCreateFailed, UIExpectsTTY, UnimplementedProviderAction,
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+