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