dtk-client 0.7.4.1 → 0.7.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/bin/dtk +10 -3
  3. data/bin/dtk-shell +1 -1
  4. data/lib/command_helpers/git_repo.rb +26 -20
  5. data/lib/command_helpers/jenkins_client.rb +4 -3
  6. data/lib/command_helpers/service_importer.rb +37 -25
  7. data/lib/commands.rb +2 -2
  8. data/lib/commands/common/thor/assembly_workspace.rb +185 -173
  9. data/lib/commands/common/thor/base_command_helper.rb +42 -0
  10. data/lib/commands/common/thor/clone.rb +1 -1
  11. data/lib/commands/common/thor/module.rb +37 -58
  12. data/lib/commands/common/thor/module/import.rb +1 -1
  13. data/lib/commands/common/thor/pull_from_remote.rb +7 -12
  14. data/lib/commands/common/thor/purge_clone.rb +1 -1
  15. data/lib/commands/common/thor/push_clone_changes.rb +3 -1
  16. data/lib/commands/common/thor/task_status.rb +52 -75
  17. data/lib/commands/common/thor/task_status/refresh_mode.rb +56 -0
  18. data/lib/commands/common/thor/task_status/snapshot_mode.rb +11 -0
  19. data/lib/commands/common/thor/task_status/stream_mode.rb +31 -0
  20. data/lib/commands/common/thor/task_status/stream_mode/element.rb +90 -0
  21. data/lib/commands/common/thor/task_status/stream_mode/element/no_results.rb +10 -0
  22. data/lib/commands/common/thor/task_status/stream_mode/element/render.rb +88 -0
  23. data/lib/commands/common/thor/task_status/stream_mode/element/stage.rb +13 -0
  24. data/lib/commands/common/thor/task_status/stream_mode/element/task_end.rb +10 -0
  25. data/lib/commands/common/thor/task_status/stream_mode/element/task_start.rb +10 -0
  26. data/lib/commands/thor/account.rb +10 -8
  27. data/lib/commands/thor/assembly.rb +9 -2
  28. data/lib/commands/thor/component_module.rb +0 -52
  29. data/lib/commands/thor/library.rb +1 -0
  30. data/lib/commands/thor/node.rb +1 -36
  31. data/lib/commands/thor/node_template.rb +4 -47
  32. data/lib/commands/thor/service.rb +57 -46
  33. data/lib/commands/thor/service_module.rb +2 -49
  34. data/lib/commands/thor/target.rb +7 -7
  35. data/lib/commands/thor/workspace.rb +44 -27
  36. data/lib/context_router.rb +4 -0
  37. data/lib/core.rb +71 -99
  38. data/lib/domain/response.rb +9 -0
  39. data/lib/domain/response/error_handler.rb +61 -0
  40. data/lib/dtk-client/version.rb +1 -1
  41. data/lib/dtk_client.rb +14 -0
  42. data/lib/dtk_error.rb +91 -0
  43. data/lib/error.rb +3 -9
  44. data/lib/execute/cli_pure/cli_rerouter.rb +82 -0
  45. data/lib/parser/adapters/thor.rb +3 -0
  46. data/lib/shell.rb +2 -1
  47. data/lib/shell/domain/context_params.rb +2 -0
  48. data/lib/util/console.rb +1 -1
  49. data/lib/util/os_util.rb +1 -0
  50. data/lib/util/remote_dependency_util.rb +20 -3
  51. data/lib/view_processor/table_print.rb +7 -25
  52. metadata +17 -5
  53. data/lib/commands/common/thor/test_action_agent.rb +0 -39
  54. data/lib/commands/thor/repo.rb +0 -35
@@ -0,0 +1,56 @@
1
+ module DTK::Client
2
+ class TaskStatus
3
+ class RefreshMode < self
4
+ def task_status(opts={})
5
+ begin
6
+ response = nil
7
+ loop do
8
+ response = post_call(opts)
9
+ return response unless response.ok?
10
+
11
+ # stop pulling when top level task succeds, fails or timeout
12
+ if response and response.data and response.data.first
13
+ #TODO: may fix in server, but now top can have non executing state but a concurrent branch can execute; so
14
+ #chanding bloew for time being
15
+ #break unless response.data.first["status"].eql? "executing"
16
+ # TODO: There is bug where we do not see executing status on start so we have to wait until at
17
+ # least one 'successed' has been found
18
+
19
+ top_task_failed = response.data.first['status'].eql?('failed')
20
+ is_pending = (response.data.select {|r|r["status"].nil? }).size > 0
21
+ is_executing = (response.data.select {|r|r["status"].eql? "executing"}).size > 0
22
+ is_failed = (response.data.select {|r|r["status"].eql? "failed"}).size > 0
23
+ is_cancelled = response.data.first["status"].eql?("cancelled")
24
+
25
+ # commented out because of DTK-1804
26
+ # when some of the converge tasks fail, stop task-status --wait and set task status to '' for remaining tasks which are not executed
27
+ # if is_failed
28
+ # response.data.each {|r| (r["status"] = "") if r["status"].eql?("executing")}
29
+ # is_cancelled = true
30
+ # end
31
+ is_cancelled = true if top_task_failed
32
+
33
+ unless (is_executing || is_pending) && !is_cancelled
34
+ system('clear')
35
+ response.print_error_table = true
36
+ response.render_table(:task_status)
37
+ return response
38
+ end
39
+ end
40
+
41
+ response.render_table(:task_status)
42
+ system('clear')
43
+ response.render_data(true)
44
+
45
+ Console.wait_animation("Watching '#{@object_type}' task status [ #{DEBUG_SLEEP_TIME} seconds refresh ] ", DEBUG_SLEEP_TIME)
46
+ end
47
+ rescue Interrupt => e
48
+ puts ""
49
+ # this tells rest of the flow to skip rendering of this response
50
+ response.skip_render = true unless response.nil?
51
+ end
52
+
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,11 @@
1
+ module DTK::Client
2
+ class TaskStatus
3
+ class SnapshotMode < self
4
+ def task_status(opts={})
5
+ response = post_call(opts)
6
+ response.print_error_table = true
7
+ response.render_table(:task_status)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,31 @@
1
+ require 'hirb'
2
+ module DTK::Client
3
+ class TaskStatus
4
+ class StreamMode < self
5
+ require File.expand_path('stream_mode/element',File.dirname(__FILE__))
6
+
7
+ def get_and_render()
8
+ Element.get_and_render_task_start(self)
9
+ Element.get_and_render_stages(self,:wait => WaitWhenNoResults)
10
+ Response::Ok.new()
11
+ end
12
+
13
+ WaitWhenNoResults = 5 #in seconds
14
+ # making this public for this class and its children
15
+ def post_call(*args)
16
+ super
17
+ end
18
+
19
+ private
20
+
21
+ # This uses a cursor based interface to the server
22
+ # start_index: START_INDEX
23
+ # end_index: END_INDEX
24
+ # convention is start_position = 0 and end_position = 0 means top level task with start time
25
+ def post_body(opts={})
26
+ ret = super(opts)
27
+ ret.merge(:start_index => opts[:start_index], :end_index => opts[:end_index])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,90 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ require File.expand_path('element/task_start',File.dirname(__FILE__))
4
+ require File.expand_path('element/task_end',File.dirname(__FILE__))
5
+ require File.expand_path('element/stage',File.dirname(__FILE__))
6
+ require File.expand_path('element/no_results',File.dirname(__FILE__))
7
+ require File.expand_path('element/render',File.dirname(__FILE__))
8
+ include RenderMixin
9
+
10
+ def initialize(response_element)
11
+ @response_element = response_element
12
+ end
13
+
14
+ def self.get_and_render_task_start(task_status_handle)
15
+ render_elements(TaskStart.get(task_status_handle))
16
+ end
17
+
18
+ # opts has
19
+ # :wait - amount to wait if get no results (required)
20
+ def self.get_and_render_stages(task_status_handle,opts={})
21
+ unless wait = opts[:wait]
22
+ raise DtkError::Client, "opts[:wait] must be set"
23
+ end
24
+
25
+ stage = 1
26
+ task_end = false
27
+ until task_end do
28
+ elements = Stage.get(task_status_handle,stage)
29
+ if no_results_yet?(elements)
30
+ sleep wait
31
+ next
32
+ end
33
+
34
+ render_elements(elements)
35
+
36
+ if task_end?(elements)
37
+ task_end = true
38
+ else
39
+ stage += 1
40
+ end
41
+ end
42
+ end
43
+
44
+ def render()
45
+ #TODO: stub
46
+ #TODO: make this nil and overwride all elements types to render
47
+ pp [:element,self.class,self]
48
+ end
49
+
50
+ private
51
+ # opts will have
52
+ # :start_index
53
+ # :end_index
54
+ def self.get_task_status_elements(task_status_handle,element_type,opts={})
55
+ response = task_status_handle.post_call(opts.merge(:form => :stream_form))
56
+ create_elements(response)
57
+ end
58
+
59
+ def self.create_elements(response)
60
+ response_elements = response.data
61
+ unless response_elements.kind_of?(Array)
62
+ raise DtkError::Client.new("Unexpected that response.data no at array")
63
+ end
64
+ response_elements.map{|el|create(el)}
65
+ end
66
+ def self.create(response_element)
67
+ type = response_element['type']
68
+ case type && type.to_sym
69
+ when :task_start then TaskStart.new(response_element)
70
+ when :task_end then TaskEnd.new(response_element)
71
+ when :stage then Stage.new(response_element)
72
+ when :no_results then NoResults.new(response_element)
73
+ else raise DtkError::Client.new("Unexpected element type '#{type}'")
74
+ end
75
+ end
76
+
77
+ def self.task_end?(elements)
78
+ elements.empty? or elements.last.kind_of?(TaskEnd)
79
+ end
80
+
81
+ def self.no_results_yet?(elements)
82
+ elements.find{|el|el.kind_of?(NoResults)}
83
+ end
84
+
85
+ def self.render_elements(elements)
86
+ elements.each{|el|el.render()}
87
+ end
88
+
89
+ end
90
+ end; end
@@ -0,0 +1,10 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ class NoResults < self
4
+ def task_end?()
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end; end
10
+
@@ -0,0 +1,88 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ module RenderMixin
4
+ end
5
+ end
6
+ end; end
7
+
8
+ =begin
9
+ def task_status_old()
10
+ current_index = 1
11
+ last_printed_index = 0
12
+ success_indices = []
13
+ loop do
14
+ response = post_call(:form => :stream_form)
15
+ return response unless response.ok?
16
+
17
+ current_tasks = response.data.select { |el| el['index'] == current_index }
18
+ main_task = current_tasks.find { |el| el['sub_index'].nil? }
19
+
20
+ # this means this is last tasks
21
+ unless main_task
22
+ print_succeeded_tasks(response.data, success_indices)
23
+ return Response::Ok.new()
24
+ end
25
+
26
+ case main_task['status']
27
+ when 'executing'
28
+ if (last_printed_index != current_index)
29
+ OsUtil.clear_screen
30
+ print_succeeded_tasks(response.data, success_indices)
31
+ print_tasks(current_tasks)
32
+ last_printed_index = current_index
33
+ end
34
+ when 'succeeded'
35
+ success_indices << current_index
36
+ current_index += 1
37
+ when nil
38
+ # ignore
39
+ else
40
+ errors = current_tasks.collect { |ct| ct['errors'] }.compact
41
+ error_msg = errors.collect { |err| err['message'] }.uniq.join(', ')
42
+ raise DtkError, "We've run into an error on task '#{main_task['type']}' status '#{main_task['status']}', error: #{error_msg}"
43
+ end
44
+
45
+ sleep(5)
46
+ end
47
+ end
48
+
49
+ private
50
+ def print_tasks(tasks)
51
+ hirb_options = {
52
+ :headers => nil,
53
+ :filters => [Proc.new { |a| append_to(25, a) },
54
+ Proc.new { |a| append_to(15, a)},
55
+ Proc.new { |a| append_to(15, a)},
56
+ Proc.new { |a| append_to(8, a)}],
57
+ :unicode => true,
58
+ :description => false
59
+ }
60
+
61
+ tasks.each do |task|
62
+ node_name = task['node'] ? task['node']['name'] : ''
63
+
64
+ puts Hirb::Helpers::AutoTable.render([[task['type'], task['status'], node_name, task['duration'], parse_date(task['started_at']), parse_date(task['ended_at'])]], hirb_options)
65
+ end
66
+ end
67
+
68
+ def print_succeeded_tasks(tasks, success_indices)
69
+ succeeded_tasks = tasks.select { |task| success_indices.include?(task['index']) }
70
+ print_tasks(succeeded_tasks)
71
+ end
72
+
73
+ def parse_date(string_date)
74
+ string_date.nil? ? (' ' * 17) : DateTime.parse(string_date).strftime('%H:%M:%S %d/%m/%y')
75
+ end
76
+
77
+ def append_to(number_of_chars, value)
78
+ value ||= ''
79
+ value.strip!
80
+ appending_str = ' ' * (number_of_chars - value.size)
81
+ value.insert(0, appending_str)
82
+ end
83
+ end
84
+ end
85
+ end
86
+
87
+ =end
88
+
@@ -0,0 +1,13 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ class Stage < self
4
+ def self.get(task_status_handle,stage_num)
5
+ get_stages(task_status_handle,stage_num,stage_num)
6
+ end
7
+
8
+ def self.get_stages(task_status_handle,start_stage_num,end_stage_num)
9
+ get_task_status_elements(task_status_handle,:stage,:start_index => start_stage_num, :end_index => end_stage_num)
10
+ end
11
+ end
12
+ end
13
+ end; end
@@ -0,0 +1,10 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ class TaskEnd < self
4
+ def task_end?()
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end; end
10
+
@@ -0,0 +1,10 @@
1
+ module DTK::Client; class TaskStatus::StreamMode
2
+ class Element
3
+ class TaskStart < self
4
+ def self.get(task_status_handle)
5
+ get_task_status_elements(task_status_handle,:task_start,:start_index => 0, :end_index => 0)
6
+ end
7
+ end
8
+ end
9
+ end; end
10
+
@@ -33,7 +33,7 @@ module DTK::Client
33
33
  [response, key_exists_already]
34
34
  end
35
35
 
36
- def self.add_key(path_to_key, name='dtk-client')
36
+ def self.add_key(path_to_key, first_registration=false, name='dtk-client')
37
37
  match, matched_username = nil, nil
38
38
 
39
39
  unless File.file?(path_to_key)
@@ -45,6 +45,7 @@ module DTK::Client
45
45
 
46
46
  post_body = { :rsa_pub_key => rsa_pub_key.chomp }
47
47
  post_body.merge!(:username => name.chomp) if name
48
+ post_body.merge!(:first_registration => first_registration)
48
49
 
49
50
  proper_response = nil
50
51
  response, key_exists_already = Account.internal_add_user_access("account/add_user_direct_access", post_body, 'service module')
@@ -58,7 +59,8 @@ module DTK::Client
58
59
  repo_manager_fingerprint,repo_manager_dns = response.data_ret_and_remove!(:repo_manager_fingerprint,:repo_manager_dns)
59
60
 
60
61
  SSHUtil.update_ssh_known_hosts(repo_manager_dns,repo_manager_fingerprint)
61
- name ||= response.data["new_username"]
62
+ name = response.data["new_username"]
63
+
62
64
  OsUtil.print("SSH key '#{name}' added successfully!", :yellow)
63
65
 
64
66
  end
@@ -117,7 +119,7 @@ module DTK::Client
117
119
  name, path_to_key = context_params.retrieve_arguments([:option_1!, :option_2],method_argument_names)
118
120
  path_to_key ||= SSHUtil.default_rsa_pub_key_path()
119
121
 
120
- response, matched, matched_username = Account.add_key(path_to_key, name)
122
+ response, matched, matched_username = Account.add_key(path_to_key, false, name)
121
123
 
122
124
  if matched
123
125
  DTK::Client::OsUtil.print("Provided SSH pub key has already been added.", :yellow)
@@ -127,8 +129,8 @@ module DTK::Client
127
129
  DTK::Client::Configurator.add_current_user_to_direct_access() if response.ok?
128
130
  end
129
131
 
130
- if response.ok? && !response.data(:registered_with_repoman)
131
- OsUtil.print("Warning: We were not able to register your key with remote catalog! Contact DTK team for more infromation.", :yellow)
132
+ if response.ok? && response.data(:repoman_registration_error)
133
+ OsUtil.print("Warning: We were not able to register your key with remote catalog! #{response.data(:repoman_registration_error)}", :yellow)
132
134
  end
133
135
 
134
136
  response.ok? ? nil : response
@@ -147,8 +149,8 @@ module DTK::Client
147
149
  response = post rest_url("account/remove_user_direct_access"), { :username => name.chomp }
148
150
  return response unless response.ok?
149
151
 
150
- if response.ok? && !response.data(:unregistered_with_repoman)
151
- OsUtil.print("Warning: We were not able to unregister your key with remote catalog!", :yellow)
152
+ if response.ok? && response.data(:repoman_registration_error)
153
+ OsUtil.print("Warning: We were not able to unregister your key with remote catalog! #{response.data(:repoman_registration_error)}", :yellow)
152
154
  end
153
155
 
154
156
  OsUtil.print("SSH key '#{name}' removed successfully!", :yellow)
@@ -171,7 +173,7 @@ module DTK::Client
171
173
  def set_catalog_credentials(context_params)
172
174
  creds = DTK::Client::Configurator.enter_catalog_credentials()
173
175
 
174
- response = post rest_url("account/set_catalog_credentials"), { :username => creds[:username], :password => creds[:password] }
176
+ response = post rest_url("account/set_catalog_credentials"), { :username => creds[:username], :password => creds[:password], :validate => true }
175
177
  return response unless response.ok?
176
178
 
177
179
  OsUtil.print("Your catalog credentials have been set!", :yellow)
@@ -194,11 +194,14 @@ module DTK::Client
194
194
  :type => :string
195
195
  method_option :settings, :type => :string, :aliases => '-s'
196
196
  def stage(context_params)
197
- assembly_template_id, name = context_params.retrieve_arguments([:assembly_id!, :option_1],method_argument_names)
197
+ assembly_template_id, service_module_id, name = context_params.retrieve_arguments([:assembly_id!, :service_module_id, :option_1],method_argument_names)
198
198
  post_body = {
199
199
  :assembly_id => assembly_template_id
200
200
  }
201
201
 
202
+ # special case when we need service module id
203
+ post_body[:service_module_id] = service_module_id if context_params.pure_cli_mode
204
+
202
205
  # using this to make sure cache will be invalidated after new assembly is created from other commands e.g.
203
206
  # 'assembly-create', 'install' etc.
204
207
  @@invalidate_map << :assembly
@@ -251,10 +254,14 @@ module DTK::Client
251
254
  method_option :settings, :type => :string, :aliases => '-s'
252
255
  def deploy(context_params)
253
256
  context_params.forward_options(options)
254
- assembly_template_id, name = context_params.retrieve_arguments([:assembly_id!, :option_1],method_argument_names)
257
+ assembly_template_id, service_module_id, name = context_params.retrieve_arguments([:assembly_id!, :service_module_id, :option_1],method_argument_names)
255
258
  post_body = {
256
259
  :assembly_id => assembly_template_id
257
260
  }
261
+
262
+ # special case when we need service module id
263
+ post_body[:service_module_id] = service_module_id if context_params.pure_cli_mode
264
+
258
265
  if commit_msg = options["commit_msg"]
259
266
  post_body.merge!(:commit_msg => commit_msg)
260
267
  end
@@ -326,58 +326,6 @@ module DTK::Client
326
326
  list_collaborators_module_aux(context_params)
327
327
  end
328
328
 
329
-
330
- #### end: commands to interact with remote repo ###
331
-
332
- #### commands to manage workspace and versioning ###
333
- =begin
334
- desc "COMPONENT-MODULE-NAME/ID create-version VERSION", "Snapshot current state of component module as a new version"
335
- def create_version(context_params)
336
- component_module_id,version = context_params.retrieve_arguments([:component_module_id!,:option_1!],method_argument_names)
337
-
338
- post_body = {
339
- :component_module_id => component_module_id,
340
- :rsa_pub_key => SSHUtil.rsa_pub_key_content()
341
- }
342
- response = post rest_url("component_module/versions"), post_body
343
- return response unless response.ok?
344
- versions = (response.data.first && response.data.first['versions'])||Array.new
345
- if versions.include?(version)
346
- return Response::Error::Usage.new("Version #{version} exists already")
347
- end
348
-
349
- component_module_name = get_module_name(component_module_id)
350
- module_location = OsUtil.module_location(:component_module,component_module_name,version)
351
- if File.directory?(module_location)
352
- return Response::Error::Usage.new("Target component module directory for version #{version} (#{module_location}) exists already; it must be deleted and this comamnd retried")
353
- end
354
-
355
- post_body = {
356
- :component_module_id => component_module_id,
357
- :version => version
358
- }
359
- response = post rest_url("component_module/create_new_version"), post_body
360
- return response unless response.ok?
361
-
362
- internal_trigger = omit_output = true
363
- clone_aux(:component_module,component_module_id,version,internal_trigger,omit_output)
364
- end
365
- =end
366
- =begin
367
- desc "COMPONENT-MODULE-NAME/ID list-versions","List all versions associated with this component module."
368
- def list_versions(context_params)
369
- component_module_id = context_params.retrieve_arguments([:component_module_id!],method_argument_names)
370
- post_body = {
371
- :component_module_id => component_module_id,
372
- :detail_to_include => ["remotes"],
373
- :rsa_pub_key => SSHUtil.rsa_pub_key_content()
374
- }
375
- response = post rest_url("component_module/versions"), post_body
376
-
377
- response.render_table(:module_version)
378
- end
379
- =end
380
-
381
329
  ##
382
330
  #
383
331
  # internal_trigger: this flag means that other method (internal) has trigger this.