vmc_knife 0.0.11 → 0.0.12
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/lib/vmc_knife/cli_extensions.rb +38 -1
- data/lib/vmc_knife/commands/knife_cmds.rb +26 -0
- data/lib/vmc_knife/data_services.rb +45 -7
- data/lib/vmc_knife/json_expander.rb +6 -5
- data/lib/vmc_knife/vmc_knife.rb +192 -4
- data/lib/vmc_knife.rb +1 -12
- metadata +4 -4
@@ -186,8 +186,45 @@ class VMC::Cli::KnifeRunner < VMC::Cli::Runner
|
|
186
186
|
else
|
187
187
|
set_cmd(:knifeapps, :data_export, @args.size) # too many
|
188
188
|
end
|
189
|
+
when 'logs','logs-all'
|
190
|
+
usage('vmc_knife logs-all')
|
191
|
+
@args.shift # consumes the argument.
|
192
|
+
if @args.size <= 3
|
193
|
+
set_cmd(:knifeapps, :logs_all, @args.size)
|
194
|
+
else
|
195
|
+
set_cmd(:knifeapps, :logs_all, @args.size) # too many
|
196
|
+
end
|
197
|
+
when 'logs-apps'
|
198
|
+
usage('vmc_knife logs-apps')
|
199
|
+
@args.shift # consumes the argument.
|
200
|
+
if @args.size <= 3
|
201
|
+
set_cmd(:knifeapps, :logs_apps, @args.size)
|
202
|
+
else
|
203
|
+
set_cmd(:knifeapps, :logs_apps, @args.size) # too many
|
204
|
+
end
|
205
|
+
when 'logs-vcap'
|
206
|
+
usage('vmc_knife logs-vcap')
|
207
|
+
@args.shift # consumes the argument.
|
208
|
+
if @args.size <= 3
|
209
|
+
set_cmd(:knifeapps, :logs_vcap, @args.size)
|
210
|
+
else
|
211
|
+
set_cmd(:knifeapps, :logs_vcap, @args.size) # too many
|
212
|
+
end
|
213
|
+
when 'logs-less','logs-shell'
|
214
|
+
usage('vmc_knife logs-less <application name>')
|
215
|
+
@args.shift # consumes the argument.
|
216
|
+
if @args.size <= 3
|
217
|
+
set_cmd(:knifeapps, :logs_less, @args.size)
|
218
|
+
else
|
219
|
+
set_cmd(:knifeapps, :logs_less, @args.size) # too many
|
220
|
+
end
|
221
|
+
when 'update-self'
|
222
|
+
usage('vmc_knife update-self')
|
223
|
+
puts "Updating vmc-knife"
|
224
|
+
`cd /tmp; [ -d "vmc-knife" ] && rm -rf vmc-knife; git clone https://github.com/hmalphettes/vmc-knife.git; cd vmc-knife; gem build vmc_knife.gemspec; gem install vmc_knife`
|
225
|
+
exit 0
|
189
226
|
when 'help'
|
190
|
-
display "vmc_knife expand-manifest|login|start/stop/restart-apps|upload-apps|configure-all|configure-recipes|configure-apps|configure-services|delete-all|configure-vcap|configure-vcap-mdns|configure-vcap-etc-hosts|data-shell|data-export/import/shrink/drop [<manifest_path>]"
|
227
|
+
display "vmc_knife expand-manifest|login|start/stop/restart-apps|upload-apps|configure-all|configure-recipes|configure-apps|configure-services|delete-all|configure-vcap|configure-vcap-mdns|configure-vcap-etc-hosts|data-shell|data-export/import/shrink/drop|logs-less|logs-all/apps/vcap|update-self [<manifest_path>]"
|
191
228
|
else
|
192
229
|
super
|
193
230
|
end
|
@@ -75,6 +75,8 @@ module VMC::Cli::Command
|
|
75
75
|
man = load_manifest(nil)
|
76
76
|
uri = man['target']
|
77
77
|
end
|
78
|
+
# if there is a port remove it.
|
79
|
+
uri = uri.split(':')[0] if uri
|
78
80
|
update_aliases = VMC::KNIFE::VCAPUpdateAvahiAliases.new(nil,man,client,/.*/)
|
79
81
|
update_hosts = VMC::KNIFE::VCAPUpdateEtcHosts.new(uri,manifest_file_path,client)
|
80
82
|
update_hosts.set_all_uris(update_aliases.all_uris)
|
@@ -129,6 +131,8 @@ module VMC::Cli::Command
|
|
129
131
|
uri = man['target']
|
130
132
|
end
|
131
133
|
raise "No uri defined" unless uri
|
134
|
+
# if there is a port remove it.
|
135
|
+
uri = uri.split(':')[0]
|
132
136
|
update_cc = _class.new(uri,config)
|
133
137
|
if update_cc.update_pending()
|
134
138
|
display "Configuring #{msg_label} with uri: #{uri}" if VMC::Cli::Config.trace
|
@@ -267,6 +271,28 @@ module VMC::Cli::Command
|
|
267
271
|
recipe_configuror(:shrink,nil,nil,data_names_regexp,manifest_file_path,
|
268
272
|
{:collection_or_table_names=>collection_or_table_names, :data_only=>true})
|
269
273
|
end
|
274
|
+
def logs_all(app_names_regexp=nil, manifest_file_path=nil)
|
275
|
+
recipe_configuror(:logs,nil,app_names_regexp,nil,manifest_file_path,
|
276
|
+
{:apps_only=>true, :log_apps=>true, :log_vcap=>true})
|
277
|
+
end
|
278
|
+
def logs_apps(app_names_regexp=nil, manifest_file_path=nil)
|
279
|
+
recipe_configuror(:logs,nil,app_names_regexp,nil,manifest_file_path,
|
280
|
+
{:apps_only=>true, :log_apps=>true, :log_vcap=>false})
|
281
|
+
end
|
282
|
+
def logs_vcap(app_names_regexp=nil, manifest_file_path=nil)
|
283
|
+
recipe_configuror(:logs,nil,app_names_regexp,nil,manifest_file_path,
|
284
|
+
{:apps_only=>true, :log_apps=>false, :log_vcap=>true})
|
285
|
+
end
|
286
|
+
def logs_less(app_names_regexp=nil, log_files_glob=nil, manifest_file_path=nil)
|
287
|
+
recipe_configuror(:logs_shell,nil,app_names_regexp,nil,manifest_file_path,
|
288
|
+
{:apps_only=>true, :log_apps=>true, :log_vcap=>false, :logs_shell=>"less",
|
289
|
+
:log_files_glob=>log_files_glob})
|
290
|
+
end
|
291
|
+
def logs_tail(app_names_regexp=nil, log_files_glob=nil, manifest_file_path=nil)
|
292
|
+
recipe_configuror(:logs_shell,nil,app_names_regexp,nil,manifest_file_path,
|
293
|
+
{:apps_only=>true, :log_apps=>true, :log_vcap=>false, :logs_shell=>"tail",
|
294
|
+
:log_files_glob=>log_files_glob})
|
295
|
+
end
|
270
296
|
|
271
297
|
def recipe_configuror(method_sym_name,recipes_regexp=nil,app_names_regexp=nil,service_names_regexp=nil,manifest_file_path=nil,opts=nil)
|
272
298
|
man = load_manifest(manifest_file_path)
|
@@ -103,7 +103,7 @@ module VMC
|
|
103
103
|
end
|
104
104
|
|
105
105
|
# command_files or command.
|
106
|
-
def self.data_service_console(credentials_hash, commands_file="",as_admin=false,exec_name=nil)
|
106
|
+
def self.data_service_console(credentials_hash, commands_file="",as_admin=false,exec_name=nil,return_value=false)
|
107
107
|
if credentials_hash['db'] #so far it has always been equal to 'db'
|
108
108
|
# It is a mongo service
|
109
109
|
#/home/ubuntu/cloudfoundry/.deployments/intalio_devbox/deploy/mongodb/bin/mongo 127.0.0.1:25003/db
|
@@ -146,6 +146,7 @@ module VMC
|
|
146
146
|
end
|
147
147
|
the_cmd = "#{cmd} #{commands_file}"
|
148
148
|
puts "#{the_cmd}" if VMC::Cli::Config.trace
|
149
|
+
return `#{the_cmd}` if return_value
|
149
150
|
puts `#{the_cmd}`
|
150
151
|
else
|
151
152
|
puts "#{cmd}" if VMC::Cli::Config.trace
|
@@ -242,8 +243,8 @@ module VMC
|
|
242
243
|
end
|
243
244
|
|
244
245
|
# Connect to the mongo js shell or the psql shell.
|
245
|
-
def shell(commands_file=nil,as_admin=false)
|
246
|
-
VMC::KNIFE.data_service_console(credentials(),commands_file,as_admin)
|
246
|
+
def shell(commands_file=nil,as_admin=false,return_value=false)
|
247
|
+
VMC::KNIFE.data_service_console(credentials(),commands_file,as_admin,nil,return_value)
|
247
248
|
end
|
248
249
|
|
249
250
|
def import(app_name=nil,file=nil)
|
@@ -359,10 +360,17 @@ module VMC
|
|
359
360
|
extension = @wrapped['director']['file_extension'] if @wrapped['director']
|
360
361
|
extension ||= "sql"
|
361
362
|
file = "#{name()}.#{extension}"
|
363
|
+
else
|
364
|
+
unless File.exists?(File.dirname(file))
|
365
|
+
raise "The output folder #{File.dirname(file)} does not exist."
|
366
|
+
end
|
362
367
|
end
|
363
368
|
archive_unzipped=file
|
364
369
|
archive_unzipped="#{name()}.sql" unless /\.sql$/ =~ extension
|
365
370
|
`touch #{archive_unzipped}`
|
371
|
+
unless File.exists? archive_unzipped
|
372
|
+
raise "Unable to create the file #{archive_unzipped}"
|
373
|
+
end
|
366
374
|
`chmod o+w #{archive_unzipped}`
|
367
375
|
puts "Exports the database #{credentials(app_name)['name']} in #{file}"
|
368
376
|
#sudo -u postgres env PGPASSWORD=intalio DBNAME=intalio DUMPFILE=intalio_dump.sql pg_dump --format=p --file=$DUMPFILE --no-owner --clean --blobs --no-acl --oid --no-tablespaces $DBNAME
|
@@ -371,6 +379,10 @@ module VMC
|
|
371
379
|
cmd = VMC::KNIFE.pg_connect_cmd(credentials(app_name), 'pg_dump', false, "--format=p --file=#{archive_unzipped} --no-owner --clean --oids --blobs --no-acl --no-privileges --no-tablespaces")
|
372
380
|
puts cmd
|
373
381
|
puts `#{cmd}`
|
382
|
+
|
383
|
+
unless File.exists? file
|
384
|
+
raise "Unable to read the file #{file}"
|
385
|
+
end
|
374
386
|
`chmod o-w #{file}`
|
375
387
|
elsif is_mongodb
|
376
388
|
if file.nil?
|
@@ -424,9 +436,12 @@ module VMC
|
|
424
436
|
|
425
437
|
# Make sure that all users who can connect to the DB can also access
|
426
438
|
# the tables.
|
427
|
-
# This workarounds the privilege issue reported
|
439
|
+
# This workarounds the privilege issue reported .... and was added to "my"
|
440
|
+
# branch of vcap's services
|
428
441
|
#
|
429
|
-
|
442
|
+
# Another workaround though really not perfect so it will stay in vmc_knife:
|
443
|
+
# the ownership of the SQL functions.
|
444
|
+
def apply_privileges(app_name=nil)
|
430
445
|
if is_postgresql()
|
431
446
|
cmd_acl="GRANT CREATE ON SCHEMA PUBLIC TO PUBLIC;\
|
432
447
|
GRANT ALL ON ALL TABLES IN SCHEMA PUBLIC TO PUBLIC;\
|
@@ -435,7 +450,30 @@ module VMC
|
|
435
450
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO PUBLIC;\
|
436
451
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO PUBLIC;\
|
437
452
|
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO PUBLIC;"
|
438
|
-
shell(cmd_acl,true)
|
453
|
+
# shell(cmd_acl,true)
|
454
|
+
|
455
|
+
# reset the owner of the functions to the current user
|
456
|
+
# when there is a 'privileged' app.
|
457
|
+
app_name ||= @wrapped['director']['bound_app'] if @wrapped['director']
|
458
|
+
if app_name
|
459
|
+
cmd_select_fcts="SELECT pg_proc.proname FROM pg_catalog.pg_proc WHERE \
|
460
|
+
pg_proc.pronamespace=(SELECT pg_namespace.oid FROM pg_catalog.pg_namespace WHERE pg_namespace.nspname = 'public') \
|
461
|
+
AND pg_proc.proowner!=(SELECT oid FROM pg_roles WHERE rolname = 'postgres')"
|
462
|
+
current_owner=credentials()['username']
|
463
|
+
unless current_owner
|
464
|
+
STDERR.puts "The application #{app_name} is not bound to the data-service #{name}; not applying the database privileges."
|
465
|
+
return
|
466
|
+
end
|
467
|
+
fcts_name=shell(cmd_select_fcts,true,true)
|
468
|
+
fcts = fcts_name.split("\n").collect do |line|
|
469
|
+
line.strip!
|
470
|
+
"'#{line}'"
|
471
|
+
end.join(',')
|
472
|
+
cmd_change_fcts_owner="UPDATE pg_catalog.pg_proc \
|
473
|
+
SET proowner = (SELECT oid FROM pg_roles WHERE rolname = '#{current_owner}')\
|
474
|
+
WHERE pg_proc.proname IN (#{fcts})"
|
475
|
+
puts `sudo -u postgres psql --dbname #{credentials()['name']} -c \"#{cmd_change_fcts_owner}\" #{PSQL_RAW_RES_ARGS}`
|
476
|
+
end
|
439
477
|
end
|
440
478
|
end
|
441
479
|
|
@@ -529,7 +567,7 @@ module VMC
|
|
529
567
|
puts "Unsupported operation 'drop' for the data-service #{name()}"
|
530
568
|
end
|
531
569
|
end
|
532
|
-
|
570
|
+
|
533
571
|
end
|
534
572
|
|
535
573
|
end
|
@@ -8,27 +8,28 @@ module VMC
|
|
8
8
|
# Reads the ip of a given interface and the mask
|
9
9
|
# defaults on eth0 then on wlan0 and then whatever it can find that is not 127.0.0.1
|
10
10
|
def self.ip_auto(interface='eth0')
|
11
|
-
|
11
|
+
ifconfig = File.exist?("/sbin/ifconfig") ? "/sbin/ifconfig" : "ifconfig"
|
12
|
+
res=`#{ifconfig} | sed -n '/#{interface}/{n;p;}' | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -1`
|
12
13
|
if interface == 'eth0' && (res.nil? || res.strip.empty?)
|
13
14
|
res = ip_auto "wlan0"
|
14
15
|
res = res[0] if res
|
15
16
|
if res.strip.empty?
|
16
17
|
#nevermind fetch the first IP you can find that is not 127.0.0.1
|
17
|
-
res
|
18
|
+
res=`#{ifconfig} | grep 'inet addr:' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}' | head -1`
|
18
19
|
end
|
19
20
|
end
|
20
21
|
res.strip! if res
|
21
22
|
unless res.empty?
|
22
23
|
# gets the Mask
|
23
|
-
line
|
24
|
+
line=`#{ifconfig} | grep 'inet addr:#{res}' | awk '{ print $1}' | head -1`
|
24
25
|
# puts "parsing ip and mask in line #{line}"
|
25
|
-
mask
|
26
|
+
mask=`#{ifconfig} | grep 'inet addr:#{res}' | grep -v '127.0.0.1' | cut -d: -f4 | awk '{ print $1}' | head -1`
|
26
27
|
mask.strip!
|
27
28
|
# puts "got ip #{res} and mask #{mask}"
|
28
29
|
return [ res, mask ]
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
32
|
+
|
32
33
|
# Derive a seed guaranteed unique on the local network according to the IP.
|
33
34
|
def self.ip_seed()
|
34
35
|
ip_mask=ip_auto()
|
data/lib/vmc_knife/vmc_knife.rb
CHANGED
@@ -147,6 +147,59 @@ module VMC
|
|
147
147
|
@wrapped
|
148
148
|
end
|
149
149
|
|
150
|
+
# look for the log folder of the deployed app.
|
151
|
+
# making the assumption we are on the same file system.
|
152
|
+
# will use the paas APIs later.
|
153
|
+
def log(folder,log_file_glob=nil)
|
154
|
+
deployed_apps_folder="#{ENV['HOME']}/cloudfoundry/deployed_apps"
|
155
|
+
log_file_glob ||= "logs/*"
|
156
|
+
if File.exist?(deployed_apps_folder)
|
157
|
+
folder_nb=0
|
158
|
+
Dir.glob(File.join(deployed_apps_folder, "#{name()}-*")).each do |dir|
|
159
|
+
fname="#{File.basename(dir)}"
|
160
|
+
app_log_folder=File.join(folder,fname)
|
161
|
+
FileUtils.mkdir_p(app_log_folder)
|
162
|
+
if File.exist? "#{dir}/logs"
|
163
|
+
FileUtils.cp(Dir.glob(File.join("#{dir}", "logs/*")), app_log_folder)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
# look for the most recent folder where we can find the stdout file.
|
170
|
+
# fork to the shell with the 'less' command to display the contents of the file.
|
171
|
+
def log_shell(shell_cmd=nil,log_file_glob=nil)
|
172
|
+
deployed_apps_folder="#{ENV['HOME']}/cloudfoundry/deployed_apps"
|
173
|
+
shell_cmd ||= "less"
|
174
|
+
log_file_glob ||= File.join("logs","stdout.log")
|
175
|
+
if File.exist?(deployed_apps_folder)
|
176
|
+
ts_most_recent=0
|
177
|
+
most_recent_file=nil
|
178
|
+
app_deployed=false
|
179
|
+
Dir.glob(File.join(deployed_apps_folder, "#{name()}-*")).each do |dir|
|
180
|
+
app_deployed=true
|
181
|
+
Dir.glob(File.join("#{dir}", log_file_glob)).each do |logfile|
|
182
|
+
ts=File.mtime(logfile).to_i
|
183
|
+
if ts > ts_most_recent
|
184
|
+
most_recent_file=logfile
|
185
|
+
ts_most_recent = ts
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
if most_recent_file
|
190
|
+
cmd = "#{shell_cmd} #{most_recent_file}"
|
191
|
+
puts "#{cmd}" if VMC::Cli::Config.trace
|
192
|
+
exec cmd
|
193
|
+
elsif app_deployed
|
194
|
+
raise "Could not find a log file #{log_file_glob} in the deployed app folder."
|
195
|
+
else
|
196
|
+
raise "Could not find a deployed application named #{name}"
|
197
|
+
end
|
198
|
+
else
|
199
|
+
raise "Could not find the deployed application folder #{deployed_apps_folder}"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
150
203
|
end
|
151
204
|
|
152
205
|
# Read/Write the application environment. a list of strings
|
@@ -247,6 +300,24 @@ module VMC
|
|
247
300
|
@application_updaters[application.name] = application_updater
|
248
301
|
updates = application_updater.updates_pending
|
249
302
|
applications_updates[application.name] = updates if updates
|
303
|
+
# if we did bind to a database; let's re-assign the ownership of the sql functions
|
304
|
+
# to the favorite app if there is such a thing.
|
305
|
+
if updates && updates['services'] && updates['services']['add']
|
306
|
+
puts "THE ONE WE ARE DEBUGGING #{JSON.pretty_generate updates['services']}"
|
307
|
+
list_services_name=updates['services']['add']
|
308
|
+
list_services_name.each do |cf_service_name|
|
309
|
+
@data_services.each do |data_service|
|
310
|
+
if data_service.name == cf_service_name
|
311
|
+
# is this the privileged app?
|
312
|
+
priv_app_name = data_service.wrapped['director']['bound_app'] if data_service.wrapped['director']
|
313
|
+
if priv_app_name == application.name
|
314
|
+
puts "GOT THE PRIVILEGED APP #{application.name} for the service #{data_service.role_name}"
|
315
|
+
data_service.apply_privileges(priv_app_name)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
250
321
|
end
|
251
322
|
end
|
252
323
|
res['services'] = data_services_updates unless data_services_updates.empty?
|
@@ -296,6 +367,74 @@ module VMC
|
|
296
367
|
application_updater.execute
|
297
368
|
end
|
298
369
|
end
|
370
|
+
def logs_shell()
|
371
|
+
log_apps=@opts[:log_apps] if @opts
|
372
|
+
logs_shell=@opts[:logs_shell] if @opts
|
373
|
+
log_files_glob=@opts[:log_files_glob] if @opts
|
374
|
+
raise "The name of the application to read its log is required." unless log_apps
|
375
|
+
@applications.each do |application|
|
376
|
+
application.log_shell(logs_shell,log_files_glob)
|
377
|
+
end
|
378
|
+
raise "No application with this name was found."
|
379
|
+
end
|
380
|
+
def logs()
|
381
|
+
output_file=@opts[:output_file] if @opts
|
382
|
+
if @root.wrapped['logs']
|
383
|
+
man_logs=@root.wrapped['logs']
|
384
|
+
name_prefix=man_logs['prefix']
|
385
|
+
parent_output_folder=man_logs['destination']
|
386
|
+
if parent_output_folder
|
387
|
+
FileUtils.mkdir_p parent_output_folder
|
388
|
+
logs_base_url=man_logs['logs_base_url']
|
389
|
+
# TODO: clean the old files and folders if there are too many of them.
|
390
|
+
end
|
391
|
+
end
|
392
|
+
name_prefix||="cflogs-"
|
393
|
+
parent_output_folder||="/tmp"
|
394
|
+
name="#{name_prefix}#{Time.now.strftime("%Y%m%d-%H%M")}"
|
395
|
+
output_file||="#{name}.zip"
|
396
|
+
output_folder="#{parent_output_folder}/#{name}"
|
397
|
+
FileUtils.rm_rf(output_folder) if File.exist? output_folder
|
398
|
+
FileUtils.mkdir(output_folder)
|
399
|
+
log_apps=@opts[:log_apps] if @opts
|
400
|
+
log_vcap=@opts[:log_vcap] if @opts
|
401
|
+
log_apps||=false
|
402
|
+
log_vcap||=false
|
403
|
+
if log_apps
|
404
|
+
FileUtils.mkdir(File.join(output_folder, 'apps'))
|
405
|
+
@applications.each do |application|
|
406
|
+
application.log(File.join(output_folder, 'apps'))
|
407
|
+
end
|
408
|
+
end
|
409
|
+
if log_vcap
|
410
|
+
if ENV['CLOUD_FOUNDRY_CONFIG_PATH'] && File.exist?(ENV['CLOUD_FOUNDRY_CONFIG_PATH'])
|
411
|
+
vcap_log_folder = File.join(File.dirname(ENV['CLOUD_FOUNDRY_CONFIG_PATH']), "log")
|
412
|
+
else
|
413
|
+
puts "Can't find the log folder for vcap, the environment variable CLOUD_FOUNDRY_CONFIG_PATH is not defined."
|
414
|
+
end
|
415
|
+
if File.exist? vcap_log_folder
|
416
|
+
FileUtils.mkdir(File.join(output_folder, 'vcap'))
|
417
|
+
FileUtils.cp_r Dir.glob(File.join(vcap_log_folder,"*")), File.join(output_folder, 'vcap')
|
418
|
+
end
|
419
|
+
end
|
420
|
+
curr_dir=Dir.pwd
|
421
|
+
destination=parent_output_folder||curr_dir
|
422
|
+
copy_or_move=("/tmp" == parent_output_folder)?"mv":"cp"
|
423
|
+
if "/tmp" == parent_output_folder
|
424
|
+
puts "Generating a zip of the logs as #{curr_dir}/#{output_file}"
|
425
|
+
else
|
426
|
+
if logs_base_url
|
427
|
+
hostname=`hostname`.strip
|
428
|
+
puts "Logs available at http://#{hostname}.local#{logs_base_url}/#{name} and in the current directory."
|
429
|
+
end
|
430
|
+
end
|
431
|
+
`cd #{File.dirname(output_folder)}; zip -r #{output_file} #{File.basename(output_folder)}; #{copy_or_move} #{output_file} #{curr_dir}`
|
432
|
+
if "/tmp" == parent_output_folder
|
433
|
+
`rm -rf #{output_folder}`
|
434
|
+
else
|
435
|
+
`mv #{parent_output_folder}/#{output_file} #{parent_output_folder}/#{name}`
|
436
|
+
end
|
437
|
+
end
|
299
438
|
end
|
300
439
|
class DataServiceManifestApplier
|
301
440
|
attr_accessor :data_service_json, :client, :current_services, :current_services_info
|
@@ -422,6 +561,7 @@ module VMC
|
|
422
561
|
puts "Updating #{@application_json['name']} with #{updated_manifest.inspect}"
|
423
562
|
@client.update_app(@application_json['name'], updated_manifest)
|
424
563
|
end
|
564
|
+
|
425
565
|
end
|
426
566
|
end
|
427
567
|
|
@@ -515,6 +655,11 @@ module VMC
|
|
515
655
|
new_app_manifest['uris'] = @application_json['uris'] unless @application_json['uris'].nil?
|
516
656
|
new_app_manifest['services'] = @application_json['services'] unless @application_json['services'].nil?
|
517
657
|
new_app_manifest['env'] = @application_json['env'] unless @application_json['env'].nil?
|
658
|
+
if @application_json['meta']
|
659
|
+
new_app_manifest['meta'] = Hash.new if new_app_manifest['meta'].nil?
|
660
|
+
new_app_manifest['meta']['debug'] = @application_json['meta']['debug'] if @application_json['meta']['debug']
|
661
|
+
new_app_manifest['meta']['restage_on_service_change'] = @application_json['meta']['restage_on_service_change'] if @application_json['meta']['restage_on_service_change']
|
662
|
+
end
|
518
663
|
new_app_manifest
|
519
664
|
end
|
520
665
|
|
@@ -524,6 +669,7 @@ module VMC
|
|
524
669
|
services = update_services_pending()
|
525
670
|
env = update_env_pending()
|
526
671
|
memory = update_memory_pending()
|
672
|
+
meta = meta_pending()
|
527
673
|
uris = update_uris_pending()
|
528
674
|
updates = Hash.new
|
529
675
|
updates['name'] = name if name
|
@@ -531,6 +677,7 @@ module VMC
|
|
531
677
|
updates['env'] = env if env
|
532
678
|
updates['uris'] = uris if uris
|
533
679
|
updates['memory'] = memory if memory
|
680
|
+
updates['meta'] = meta if meta
|
534
681
|
updates unless updates.empty?
|
535
682
|
end
|
536
683
|
|
@@ -568,8 +715,8 @@ module VMC
|
|
568
715
|
stack_change "#{old_stack} => #{new_stack}"
|
569
716
|
end
|
570
717
|
return if model_change.nil? && stack_change.nil?
|
571
|
-
return { "stack" => stack_change } if model_change.
|
572
|
-
return { "model" => model_change } if stack_change.
|
718
|
+
return { "stack" => stack_change } if model_change.nil?
|
719
|
+
return { "model" => model_change } if stack_change.nil?
|
573
720
|
return { "stack" => stack_change, "model" => model_change }
|
574
721
|
end
|
575
722
|
def update_services_pending()
|
@@ -587,6 +734,25 @@ module VMC
|
|
587
734
|
new_services = @application_json['uris']
|
588
735
|
diff_lists(old_services,new_services)
|
589
736
|
end
|
737
|
+
# only look for debug and restage_on_service_change
|
738
|
+
def meta_pending()
|
739
|
+
old_meta = current[:meta] || current['meta'] || {}
|
740
|
+
new_meta = @application_json['meta'] || {}
|
741
|
+
old_debug = old_meta[:debug] || old_meta['debug']
|
742
|
+
new_debug = new_meta['debug']
|
743
|
+
debug_change = "#{old_debug} => #{new_debug}" if old_debug != new_debug
|
744
|
+
|
745
|
+
old_restage_on_service_change = old_meta[:restage_on_service_change]
|
746
|
+
old_restage_on_service_change = old_meta['restage_on_service_change'] unless old_restage_on_service_change == false
|
747
|
+
old_restage_on_service_change = old_restage_on_service_change.to_s unless old_restage_on_service_change.nil?
|
748
|
+
new_restage_on_service_change = new_meta['restage_on_service_change']
|
749
|
+
restage_on_service_change_change = "#{old_restage_on_service_change} => #{new_restage_on_service_change}" if old_restage_on_service_change != new_restage_on_service_change
|
750
|
+
|
751
|
+
return if debug_change.nil? && restage_on_service_change_change.nil?
|
752
|
+
return { "debug" => debug_change } if restage_on_service_change_change.nil?
|
753
|
+
return { "restage_on_service_change" => restage_on_service_change_change } if debug_change.nil?
|
754
|
+
return { "debug" => debug_change, "restage_on_service_change" => restage_on_service_change_change }
|
755
|
+
end
|
590
756
|
def diff_lists(old_services,new_services)
|
591
757
|
new_services ||= Array.new
|
592
758
|
old_services ||= Array.new
|
@@ -691,16 +857,38 @@ module VMC
|
|
691
857
|
# This is really a server-side feature.
|
692
858
|
# Replace the 127.0.0.1 localhost #{old_uri} with the new uri
|
693
859
|
class VCAPUpdateEtcHosts
|
860
|
+
# uri the uris (hostname) to set.
|
861
|
+
# accepted type for uri: space separated list; array of strings;
|
862
|
+
# port appended to the hostname are also tolerated and will be stripped out.
|
694
863
|
def initialize(uri, etc_hosts_path=nil,man=nil)
|
695
864
|
@config = etc_hosts_path
|
696
865
|
@config ||="/etc/hosts"
|
697
|
-
|
866
|
+
if uri
|
867
|
+
if uri.kind_of? String
|
868
|
+
uris_arr = uri.split(' ')
|
869
|
+
set_all_uris(uris_arr)
|
870
|
+
elsif uri.kind_of? Array
|
871
|
+
set_all_uris(uri)
|
872
|
+
end
|
873
|
+
end
|
698
874
|
raise "The config file #{@config} does not exist." unless File.exists? @config
|
699
875
|
end
|
700
876
|
def set_all_uris(uris_arr)
|
701
|
-
|
877
|
+
if @uri
|
878
|
+
if @uri.kind_of? String
|
879
|
+
uris_arr.push @uri
|
880
|
+
elsif @uri.kind_of? Array
|
881
|
+
uris_arr = @uri + uris_arr
|
882
|
+
end
|
883
|
+
end
|
884
|
+
#remove the port if there is one.
|
885
|
+
uris_arr.collect! do |u| u.split(':')[0] end
|
702
886
|
uris_arr.sort!
|
703
887
|
uris_arr.uniq!
|
888
|
+
# filter out the local uris: we rely on mdns for them.
|
889
|
+
#uris_arr.delete_if do |u| u =~ /\.local$/ end
|
890
|
+
# for now only filter the local url with a '-'
|
891
|
+
uris_arr.delete_if do |u| u =~ /-.*\.local$/ end
|
704
892
|
@uri = uris_arr.join(' ')
|
705
893
|
end
|
706
894
|
def update_pending()
|
data/lib/vmc_knife.rb
CHANGED
@@ -3,21 +3,10 @@ module VMCKNIFE
|
|
3
3
|
end
|
4
4
|
require "#{VMCKNIFE::ROOT_REL}/restclient/restclient_add_timeout.rb"
|
5
5
|
|
6
|
-
|
7
|
-
module VMC
|
8
|
-
module Cli
|
9
|
-
module Command
|
10
|
-
autoload :Knife, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
11
|
-
autoload :Knifeapps, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
12
|
-
autoload :Knifemisc, "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
|
18
6
|
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/json_expander"
|
19
7
|
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/vmc_helper"
|
20
8
|
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/vmc_knife"
|
21
9
|
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/data_services"
|
22
10
|
|
23
11
|
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/cli_extensions"
|
12
|
+
require "#{VMCKNIFE::ROOT_REL}/vmc_knife/commands/knife_cmds"
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmc_knife
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 12
|
10
|
+
version: 0.0.12
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Intalio Pte
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-
|
18
|
+
date: 2012-02-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: vmc
|