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.
@@ -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
+