rookout 0.1.0 → 0.1.56

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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rookout/atfork.rb +73 -0
  3. data/lib/rookout/augs/actions/action_run_processor.rb +4 -3
  4. data/lib/rookout/augs/aug.rb +33 -91
  5. data/lib/rookout/augs/aug_factory.rb +94 -27
  6. data/lib/rookout/augs/aug_rate_limiter.rb +50 -47
  7. data/lib/rookout/augs/augs_manager.rb +3 -1
  8. data/lib/rookout/augs/conditions/condition.rb +4 -2
  9. data/lib/rookout/augs/limits_manager.rb +32 -0
  10. data/lib/rookout/augs/locations/location.rb +75 -1
  11. data/lib/rookout/augs/locations/location_exception_handler.rb +22 -0
  12. data/lib/rookout/augs/locations/location_file_line.rb +21 -5
  13. data/lib/rookout/com_ws/agent_com_ws.rb +97 -58
  14. data/lib/rookout/com_ws/backoff.rb +5 -10
  15. data/lib/rookout/com_ws/command_handler.rb +1 -1
  16. data/lib/rookout/com_ws/envelope_wrapper.rb +68 -0
  17. data/lib/rookout/com_ws/git.rb +1 -1
  18. data/lib/rookout/com_ws/information.rb +95 -4
  19. data/lib/rookout/com_ws/output.rb +69 -21
  20. data/lib/rookout/com_ws/pinger.rb +41 -0
  21. data/lib/rookout/com_ws/websocket_client.rb +173 -0
  22. data/lib/rookout/commit.rb +3 -0
  23. data/lib/rookout/config.rb +94 -18
  24. data/lib/rookout/exceptions.rb +147 -12
  25. data/lib/rookout/interface.rb +95 -32
  26. data/lib/rookout/logger.rb +39 -10
  27. data/lib/rookout/processor/namespace_serializer.rb +2 -2
  28. data/lib/rookout/processor/namespace_serializer2.rb +331 -0
  29. data/lib/rookout/processor/namespaces/container_namespace.rb +5 -0
  30. data/lib/rookout/processor/namespaces/frame_namespace.rb +20 -17
  31. data/lib/rookout/processor/namespaces/namespace.rb +3 -2
  32. data/lib/rookout/processor/namespaces/noop_namespace.rb +4 -8
  33. data/lib/rookout/processor/namespaces/ruby_object_namespace.rb +39 -22
  34. data/lib/rookout/processor/namespaces/ruby_object_serializer.rb +15 -12
  35. data/lib/rookout/processor/namespaces/ruby_utils_namespace.rb +0 -4
  36. data/lib/rookout/processor/namespaces/stack_namespace.rb +6 -4
  37. data/lib/rookout/processor/namespaces/traceback_namespace.rb +13 -9
  38. data/lib/rookout/processor/operations/set_operation.rb +6 -1
  39. data/lib/rookout/processor/paths/arithmetic_path.rb +5 -3
  40. data/lib/rookout/processor/paths/canopy/actions.rb +5 -1
  41. data/lib/rookout/processor/paths/canopy/consts.rb +6 -4
  42. data/lib/rookout/processor/paths/canopy/maps.rb +286 -286
  43. data/lib/rookout/processor/paths/canopy/markers.rb +35 -4
  44. data/lib/rookout/processor/processor_factory.rb +0 -2
  45. data/lib/rookout/processor/rook_error.rb +6 -1
  46. data/lib/rookout/protobuf/controller_info_pb.rb +1 -0
  47. data/lib/rookout/protobuf/messages_pb.rb +54 -0
  48. data/lib/rookout/protobuf/variant2_pb.rb +42 -0
  49. data/lib/rookout/protobuf/variant_pb.rb +22 -0
  50. data/lib/rookout/rookout_singleton.rb +23 -5
  51. data/lib/rookout/sanitizer.rb +22 -0
  52. data/lib/rookout/services/position.rb +92 -75
  53. data/lib/rookout/services/tracer.rb +30 -16
  54. data/lib/rookout/start.rb +12 -0
  55. data/lib/rookout/trigger_services.rb +2 -2
  56. data/lib/rookout/user_warnings.rb +2 -0
  57. data/lib/rookout/utils.rb +34 -0
  58. data/lib/rookout/version.rb +1 -2
  59. data/lib/rookout.rb +4 -0
  60. metadata +77 -51
@@ -1,10 +1,84 @@
1
1
  module Rookout
2
2
  module Augs
3
3
  module Locations
4
+ require_relative "../../processor/rook_error"
5
+
6
+ MAX_LOG_CACHE_SIZE = 10
7
+
4
8
  class Location
5
- def add_aug _trigger_services, _aug
9
+ def initialize output, aug
10
+ @output = output
11
+ @aug = aug
12
+ @log_cache = []
13
+ end
14
+
15
+ def add_aug _trigger_services
6
16
  raise NotImplementedError
7
17
  end
18
+
19
+ def id
20
+ @aug.id
21
+ end
22
+
23
+ def execute frame_binding, stack_trace, extracted
24
+ UserWarnings.with self do
25
+ begin
26
+ @aug.execute frame_binding, stack_trace, extracted, @output
27
+ rescue SystemExit
28
+ raise
29
+ rescue Exception => e
30
+ message = "Exception while processing Aug"
31
+ error = Processor::RookError.new e, message
32
+ notify_warning error
33
+ end
34
+ end
35
+ end
36
+
37
+ def notify_active
38
+ send_rule_status :Active
39
+ end
40
+
41
+ def notify_pending
42
+ send_rule_status :Pending
43
+ end
44
+
45
+ def notify_removed
46
+ send_rule_status :Deleted
47
+ end
48
+
49
+ def notify_error error
50
+ send_rule_status :Error, error
51
+ end
52
+
53
+ def notify_warning error
54
+ return if silence_log? error
55
+
56
+ Logger.instance.warning error.message, error.exception
57
+
58
+ # For easier testing
59
+ return if @output.nil?
60
+ @output.send_rule_status id, :Warning, error
61
+ end
62
+
63
+ private
64
+
65
+ def silence_log? error
66
+ return true if @log_cache.length >= MAX_LOG_CACHE_SIZE || @log_cache.include?(error.message)
67
+
68
+ @log_cache << error.message
69
+ false
70
+ end
71
+
72
+ def send_rule_status status, error = nil
73
+ return if @status == status
74
+
75
+ Logger.instance.info "Updating rule status for #{@id} to #{status}"
76
+ @status = status
77
+
78
+ # For easier testing
79
+ return if @output.nil?
80
+ @output.send_rule_status id, status, error
81
+ end
8
82
  end
9
83
  end
10
84
  end
@@ -0,0 +1,22 @@
1
+ module Rookout
2
+ module Augs
3
+ require_relative "../../logger"
4
+
5
+ require_relative "../../processor/rook_error"
6
+
7
+ module Locations
8
+ require_relative "location"
9
+
10
+ class LocationExceptionHandler < Location
11
+ NAME = "exception_handler".freeze
12
+
13
+ def initialize _arguments, output, aug
14
+ super output, aug
15
+ end
16
+
17
+ def add_aug _trigger_services
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -1,24 +1,40 @@
1
1
  module Rookout
2
2
  module Augs
3
+ require_relative "../../logger"
4
+
5
+ require_relative "../../processor/rook_error"
6
+
3
7
  module Locations
4
8
  require_relative "location"
5
9
 
6
10
  class LocationFileLine < Location
7
11
  NAME = "file_line".freeze
8
12
 
9
- def initialize arguments, _processor_factory
13
+ def initialize arguments, output, aug
14
+ super output, aug
10
15
  @filename = arguments["filename"]
11
16
  @lineno = arguments["lineno"]
12
17
 
18
+ # NOTE: Hashes are only used for suggestions, not for verification
13
19
  @file_hash = arguments["sha256"]
14
20
  @line_crc = arguments["line_crc32_2"]
15
- @line_unique = arguments["line_unique"] != 0
21
+ @line_unique = arguments["line_unique"] || false
16
22
  end
17
23
 
18
- attr_reader :filename, :lineno, :file_hash, :line_crc, :line_unique
24
+ attr_reader :filename
25
+ attr_reader :lineno
26
+ attr_reader :file_hash
27
+ attr_reader :line_crc
28
+ attr_reader :line_unique
19
29
 
20
- def add_aug trigger_services, aug
21
- trigger_services.get_service("position").add_aug self, aug
30
+ def add_aug trigger_services
31
+ trigger_services.get_service("position").add_aug self
32
+ rescue SystemExit
33
+ raise
34
+ rescue Exception => e
35
+ message = "Exception when adding aug"
36
+ Logger.instance.error message, e
37
+ notify_error Processor::RookError.new e, message
22
38
  end
23
39
  end
24
40
  end
@@ -1,7 +1,5 @@
1
1
  module Rookout
2
2
  module ComWs
3
- require "securerandom"
4
- require "kontena-websocket-client"
5
3
  require "event_emitter"
6
4
  require "google/protobuf/well_known_types"
7
5
  require "concurrent"
@@ -10,21 +8,30 @@ module Rookout
10
8
  require_relative "../logger"
11
9
  require_relative "../user_warnings"
12
10
  require_relative "../exceptions"
11
+ require_relative "../utils"
13
12
 
14
13
  require_relative "../processor/rook_error"
15
14
 
16
15
  require_relative "../protobuf/messages_pb"
17
16
  require_relative "../protobuf/envelope_pb"
18
17
 
18
+ require_relative "websocket_client"
19
19
  require_relative "backoff"
20
20
  require_relative "information"
21
+ require_relative "pinger"
21
22
 
22
23
  class AgentComWs
23
24
  include EventEmitter
24
25
 
25
- def initialize output, agent_host, agent_port, proxy, token, labels
26
- agent_host_with_protocl = agent_host.include?("://") ? agent_host : "ws://#{agent_host}"
27
- @uri = "#{agent_host_with_protocl}:#{agent_port}/v1"
26
+ attr_reader :pending_messages
27
+
28
+ def initialize output, agent_host, agent_port, proxy, token, labels, print_on_connect
29
+ if agent_host.nil? || agent_host.empty?
30
+ @uri = ""
31
+ else
32
+ agent_host_with_protocl = agent_host.include?("://") ? agent_host : "ws://#{agent_host}"
33
+ @uri = "#{agent_host_with_protocl}:#{agent_port}/v1"
34
+ end
28
35
  if proxy.nil? || proxy.empty?
29
36
  @proxy = nil
30
37
  else
@@ -38,37 +45,55 @@ module Rookout
38
45
  @info = Information.new labels
39
46
  reset_id
40
47
 
41
- @thread = nil
48
+ @main_thread = nil
49
+ @outgoing_thread = nil
42
50
  @pending_messages = Queue.new
51
+ @pending_messages_length = 0
43
52
 
44
53
  @running = false
45
54
  @ready_event = Concurrent::Event.new
46
55
  once("Com::Rookout::InitialAugsCommand") { @ready_event.set }
47
- end
48
56
 
49
- def add message
50
- buffer = wrap_in_envelope message
51
- if buffer.length > Config.agent_com_max_message_limit
52
- exc = Exceptions::RookMessageSizeExceeded.new buffer.length, Coonfig.agent_com_max_message_limit
53
- warning = RookError.new exc, message
54
- UserWarnings.notify_warning warning
57
+ @print_on_initial_connection = print_on_connect
58
+ end
55
59
 
56
- Logger.instance.warn "Dropping message, size was #{buffer.length} which is over the message size limit"
57
- return
60
+ def add envelope_wrapper
61
+ msg_size = envelope_wrapper.calculate_size
62
+ if @pending_messages_length + msg_size > Config.agent_com_max_queue_messages_length ||
63
+ queue_full?
64
+ raise Exceptions::RookOutputQueueFull
58
65
  end
59
66
 
60
- @pending_messages.push buffer if @pending_messages.length < Config.agent_com_max_queued_messages
67
+ @pending_messages.push envelope_wrapper
68
+ @pending_messages_length += msg_size
69
+ end
70
+
71
+ def queue_full?
72
+ @pending_messages.length >= Config.agent_com_max_queued_messages
61
73
  end
62
74
 
63
75
  def connect
64
76
  @running = true
65
77
 
66
- @thread = Thread.new { connection_thread }
67
- @thread.name = "rookout-connection-thread"
78
+ @main_thread = Thread.new { connection_thread }
79
+ @main_thread.name = "rookout-connection-thread"
80
+ end
81
+
82
+ def stop
83
+ @running = false
84
+
85
+ # Ask outgoing thread to exit (if running)
86
+ @pending_messages << ExitMessage.new(@outgoing_thread)
87
+
88
+ @main_thread.join
68
89
  end
69
90
 
70
91
  def wait_for_ready
71
- @ready_event.wait Config.agent_com_timeout
92
+ is_finished = @ready_event.wait Config.agent_com_timeout
93
+ # We didn't finish - will keep trying in the background
94
+ raise Exceptions::RookCommunicationException unless is_finished
95
+
96
+ # We finished - raise if we failed
72
97
  raise @connection_error if @connection_error
73
98
  end
74
99
 
@@ -85,50 +110,49 @@ module Rookout
85
110
 
86
111
  while @running
87
112
  begin
88
- backoff.before_connection_attempt
89
- Kontena::Websocket::Client.connect(@uri, **create_options) do |client|
90
- register client
113
+ client = open_new_connection
91
114
 
92
- Logger.instance.debug "WebSocket connected successfully"
93
- @token_valid = true
94
- backoff.after_connect
95
-
96
- connection_pump client
115
+ if @print_on_initial_connection
116
+ @print_on_initial_connection = false
117
+ Utils.quiet_puts "[Rookout] Successfully connected to controller."
118
+ Logger.instance.debug "[Rookout] Agent ID is #{@agent_id}"
97
119
  end
120
+ Logger.instance.debug "WebSocket connected successfully"
121
+ Logger.instance.info "Finished initialization"
122
+
123
+ @token_valid = true
124
+ backoff.after_connect
125
+
126
+ connection_pump client
98
127
  rescue Exception => e
99
- if !@token_valid && e.is_a?(Kontena::Websocket::ProtocolError) && e.message.include?("403")
128
+ if !@token_valid && e.message.include?("403")
100
129
  @connection_error = Exceptions::RookInvalidToken.new @token
101
130
  @ready_event.set
102
131
  end
103
132
 
104
- Logger.instance.info "Connection failed; reason = #{e.message}"
133
+ if e.message.include? "400"
134
+ @connection_error = Exceptions::RookWebSocketError.new 400
135
+ @ready_event.set
136
+ end
137
+
138
+ Logger.instance.warning "Connection failed; reason = #{e.message}"
105
139
  end
106
140
 
107
141
  backoff.after_disconnect
108
142
  Logger.instance.debug "Reconnecting"
109
143
  end
144
+ rescue Exception => e
145
+ Logger.instance.error "Unexpected error in connection_thread", e
110
146
  end
111
147
 
112
- def create_options
113
- headers = {
114
- "User-Agent" => "RookoutAgent/#{Config.rookout_version}+#{Config.rookout_commit}"
115
- }
116
-
117
- headers["X-Rookout-Token"] = @token unless @token.nil?
118
-
119
- # NOTE: WE DONT HAVE PROXY SUPPORT (YET) - THIS WILL PROBABLY REQUIRE FORKING KONTENA
120
- { headers: headers,
121
- connect_timeout: Config.agent_com_timeout,
122
- open_timeout: Config.agent_com_timeout,
123
- ping_interval: Config.agent_com_ping_interval,
124
- ping_timeout: Config.agent_com_ping_timeout }
125
- end
126
-
127
- def register client
128
- Logger.instance.info "Registering agent with id #{@agent_id}"
148
+ def open_new_connection
149
+ client = WebsocketClient.new @uri, @proxy, @token
150
+ client.connect
129
151
 
130
152
  msg = Com::Rookout::NewAgentMessage.new agent_info: @info.pack
131
- client.send wrap_in_envelope(msg)
153
+ client.send_frame wrap_in_envelope(msg)
154
+
155
+ client
132
156
  end
133
157
 
134
158
  ACCEPTED_MESSAGE_TYPES = [
@@ -140,11 +164,18 @@ module Rookout
140
164
  ].freeze
141
165
 
142
166
  def connection_pump client
143
- on_outgoing_exit = proc { client.disconnect }
144
- send_thread = Thread.new { outgoing client, on_outgoing_exit }
145
- send_thread.name = "rookout-outgoing-thread"
167
+ on_outgoing_exit = proc {
168
+ begin
169
+ client.close
170
+ rescue Exception => e
171
+ Logger.instance.error "Unexpected error exiting outgoing thread", e
172
+ end
173
+ }
174
+
175
+ @outgoing_thread = Thread.new { outgoing client, on_outgoing_exit }
176
+ @outgoing_thread.name = "rookout-outgoing-thread"
146
177
 
147
- client.read do |raw_message|
178
+ message_handler = proc do |raw_message|
148
179
  envelope = Com::Rookout::Envelope.decode raw_message.pack("c*")
149
180
 
150
181
  ACCEPTED_MESSAGE_TYPES.each do |klass|
@@ -153,28 +184,35 @@ module Rookout
153
184
  end
154
185
  end
155
186
 
187
+ client.connection_pump message_handler
188
+
156
189
  Logger.instance.debug "Incoming loop - socket disconnected"
157
190
 
158
191
  @pending_messages.push ExitMessage.new(send_thread)
159
- send_thread.join
192
+ @outgoing_thread.join
193
+ @outgoing_thread = nil
160
194
  end
161
195
 
162
196
  def outgoing client, on_exit
163
- loop do
197
+ Pinger.new(client, Config.agent_com_ping_interval, Config.agent_com_ping_timeout).repeat do
164
198
  begin
165
- msg = @pending_messages.pop true
199
+ envelope_wrapper = @pending_messages.pop true
166
200
  rescue ThreadError
167
201
  sleep 0.25
168
202
  next
169
203
  end
170
204
 
171
- if msg.is_a? ExitMessage
205
+ msg = envelope_wrapper.envelope
206
+ @pending_messages_length -= envelope_wrapper.calculate_size
207
+
208
+ case msg
209
+ when ExitMessage
172
210
  break if msg.thread == Thread.current
173
- elsif msg.is_a? FlushMessage
211
+ when FlushMessage
174
212
  msg.event.set
175
213
  else
176
214
  begin
177
- client.send msg
215
+ client.send_frame msg
178
216
  rescue RuntimeError
179
217
  @queue << msg
180
218
  break
@@ -184,6 +222,7 @@ module Rookout
184
222
  rescue Exception => e
185
223
  Logger.instance.exception "Outgoing thread failed", e
186
224
  ensure
225
+ Logger.instance.debug "Outgoing thread exiting"
187
226
  on_exit.call
188
227
  end
189
228
 
@@ -196,7 +235,7 @@ module Rookout
196
235
  end
197
236
 
198
237
  def reset_id
199
- @agent_id = SecureRandom.uuid
238
+ @agent_id = Utils.uuid
200
239
  @output.agent_id = @agent_id
201
240
  @info.agent_id = @agent_id
202
241
  end
@@ -4,25 +4,20 @@ module Rookout
4
4
 
5
5
  class Backoff
6
6
  def initialize
7
- @connected = false
8
- @last_successful_connection = Time.mktime 1970
9
- reset_backoff
10
- end
11
-
12
- def before_connection_attempt
13
- return unless Time.new > @last_successful_connection + Config.backoff_reset_time
7
+ @connect_time = nil
14
8
  reset_backoff
15
9
  end
16
10
 
17
11
  def after_disconnect
18
- @connected = false
12
+ reset_backoff if @connect_time && Time.new > @connect_time + Config.backoff_reset_time
13
+ @connect_time = nil
14
+
19
15
  sleep @next_backoff
20
16
  @next_backoff = [@next_backoff * 2, Config.backoff_max_time].min
21
17
  end
22
18
 
23
19
  def after_connect
24
- @connected = true
25
- @last_successful_connection = Time.now
20
+ @connect_time = Time.now
26
21
  end
27
22
 
28
23
  private
@@ -5,10 +5,10 @@ module Rookout
5
5
  class CommandHandler
6
6
  def initialize agent_com, augs_manager
7
7
  agent_com.on "Com::Rookout::InitialAugsCommand" do |initial_augs|
8
+ Config.update_config initial_augs.sdk_configuration
8
9
  augs = initial_augs.augs.map { |aug_json| JSON.parse aug_json }
9
10
  augs_manager.initialize_augs augs
10
11
  end
11
-
12
12
  agent_com.on "Com::Rookout::AddAugCommand" do |command|
13
13
  augs_manager.add_aug JSON.parse(command.aug_json)
14
14
  end
@@ -0,0 +1,68 @@
1
+ require_relative "../protobuf/envelope_pb"
2
+ require_relative "../processor/namespace_serializer2"
3
+
4
+
5
+ class EnvelopeWrapperBase
6
+ def wrap_in_envelope message
7
+ any_message = Google::Protobuf::Any.pack message
8
+ timestamp = Google::Protobuf::Timestamp.new
9
+ timestamp.from_time Time.new
10
+ envelope = Com::Rookout::Envelope.new msg: any_message, timestamp: timestamp
11
+ Com::Rookout::Envelope.encode envelope
12
+ end
13
+
14
+ def envelope
15
+ raise NotImplementedError
16
+ end
17
+
18
+ def calculate_size
19
+ raise NotImplementedError
20
+ end
21
+ end
22
+
23
+ class Variant2EnvelopeWrapper < EnvelopeWrapperBase
24
+ def initialize agent_id, aug_id, report_id, arguments
25
+ super()
26
+
27
+ @aug_report_message = Com::Rookout::AugReportMessage.new agent_id: agent_id,
28
+ aug_id: aug_id,
29
+ report_id: report_id
30
+ @serializer = Rookout::Processor::NamespaceSerializer2.new
31
+ @aug_report_message.arguments2 = @serializer.dump arguments, true
32
+
33
+ @estimated_length = @serializer.estimated_pending_bytes
34
+ @envelope = nil
35
+ end
36
+
37
+ def envelope
38
+ if @envelope.nil?
39
+ @serializer.string_cache.each do |key, value|
40
+ @aug_report_message.strings_cache[key.encode "UTF-8", invalid: :replace, undef: :replace, replace: "?"] = value
41
+ end
42
+ @envelope = wrap_in_envelope @aug_report_message
43
+
44
+ @serializer = nil
45
+ @aug_report_message = nil
46
+ end
47
+ @envelope
48
+ end
49
+
50
+ def calculate_size
51
+ @estimated_length
52
+ end
53
+ end
54
+
55
+ class EnvelopeWrapper < EnvelopeWrapperBase
56
+ def initialize message
57
+ super()
58
+ @envelope = wrap_in_envelope message
59
+ end
60
+
61
+ def envelope
62
+ @envelope
63
+ end
64
+
65
+ def calculate_size
66
+ @envelope.length
67
+ end
68
+ end
@@ -42,7 +42,7 @@ module Rookout
42
42
  link_contents = File.read link_path
43
43
 
44
44
  if link_contents.start_with? "ref:"
45
- next_link = (link_contents.split " ")[1].strip
45
+ next_link = link_contents.split[1].strip
46
46
  follow_sym_links root, next_link
47
47
  else
48
48
  link_contents.strip
@@ -11,10 +11,17 @@ module Rookout
11
11
  require_relative "git"
12
12
  include Git
13
13
 
14
- def initialize labels
14
+ def initialize labels, k8s_file_path = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
15
15
  @agent_id = nil
16
16
  @labels = labels.clone
17
- @labels["rookout_debug"] = "on"
17
+ @labels["rookout_debug"] = "on" if Config.debug
18
+
19
+ k8_namespace = create_cluster_namespace k8s_file_path
20
+ unless k8_namespace == "" || @labels.key?("k8s_namespace")
21
+ @labels["k8s_namespace"] = k8_namespace
22
+ end
23
+
24
+ collect_serverless_labels
18
25
 
19
26
  @ip_addr = local_ip
20
27
 
@@ -50,6 +57,7 @@ module Rookout
50
57
  end
51
58
 
52
59
  attr_accessor :agent_id
60
+ attr_accessor :labels
53
61
 
54
62
  private
55
63
 
@@ -65,10 +73,52 @@ module Rookout
65
73
  end
66
74
  # rubocop:enable Style/ParallelAssignment
67
75
 
76
+ def create_cluster_namespace k8s_file_path
77
+ return_value = ""
78
+
79
+ # No Kubernetes is valid
80
+ if File.file? k8s_file_path
81
+ # Read the file contents and return it as result
82
+ return_value = File.read k8s_file_path
83
+ end
84
+
85
+ return_value
86
+ end
87
+
88
+ def parse_raw_git_sources
89
+ git_sources_raw = ENV["ROOKOUT_SOURCES"]
90
+ if git_sources_raw.nil?
91
+ return nil
92
+ end
93
+
94
+ git_sources = git_sources_raw.split ";"
95
+ user_git_sources = {}
96
+ git_sources.each do |url|
97
+ url_parts = url.split "#"
98
+ if url_parts.length != 2
99
+ next
100
+ end
101
+
102
+ remote_url = url_parts[0]
103
+ commit = url_parts[1]
104
+ user_git_sources[remote_url] = commit
105
+ end
106
+
107
+ user_git_sources
108
+ end
109
+
68
110
  def create_scm_information
69
- user_git_origin = Config.user_git_origin || ENV["ROOKOUT_ORIGIN"]
111
+ user_git_origin = Config.user_git_origin || ENV["ROOKOUT_REMOTE_ORIGIN"]
70
112
  user_git_commit = Config.user_git_commit || ENV["ROOKOUT_COMMIT"]
71
113
 
114
+ user_git_sources = Config.user_git_sources || parse_raw_git_sources
115
+
116
+ if !user_git_sources.nil? && !user_git_sources.empty?
117
+ user_git_sources = user_git_sources.map do |remote_url, commit|
118
+ Com::Rookout::SCMInformation::SourceInfo.new remoteOriginUrl: remote_url, commit: commit
119
+ end
120
+ end
121
+
72
122
  if user_git_origin.nil? && user_git_commit.nil?
73
123
  search_path = File.dirname File.absolute_path($PROGRAM_NAME)
74
124
  git_root = find_root search_path
@@ -78,7 +128,48 @@ module Rookout
78
128
  end
79
129
  end
80
130
 
81
- Com::Rookout::SCMInformation.new origin: user_git_origin, commit: user_git_commit
131
+ Com::Rookout::SCMInformation.new origin: user_git_origin, commit: user_git_commit, sources: user_git_sources
132
+ end
133
+
134
+ def aws_lambda?
135
+ !ENV["AWS_LAMBDA_FUNCTION_NAME"].nil?
136
+ end
137
+
138
+ def google_cloud_function?
139
+ !ENV["FUNCTION_TARGET"].nil? && !ENV["FUNCTION_SIGNATURE_TYPE"].nil?
140
+ end
141
+
142
+ def cloud_run_or_fire_base?
143
+ !ENV["K_SERVICE"].nil? &&
144
+ !ENV["K_REVISION"].nil? &&
145
+ !ENV["K_CONFIGURATION"].nil? &&
146
+ !ENV["PORT"].nil?
147
+ end
148
+
149
+ def azure_function?
150
+ !ENV["FUNCTIONS_WORKER_RUNTIME"].nil? && !ENV["WEBSITE_SITE_NAME"].nil?
151
+ end
152
+
153
+ def collect_serverless_labels
154
+ if aws_lambda?
155
+ @labels["function_name"] = ENV["AWS_LAMBDA_FUNCTION_NAME"]
156
+ @labels["aws_region"] = ENV["AWS_REGION"]
157
+
158
+ elsif google_cloud_function? || cloud_run_or_fire_base?
159
+ function_name = ENV["FUNCTION_NAME"]
160
+ if function_name.nil?
161
+ function_name = ENV["K_SERVICE"]
162
+ end
163
+ @labels["function_name"] = function_name
164
+
165
+ elsif azure_function?
166
+ @labels["function_name"] = ENV["WEBSITE_SITE_NAME"]
167
+ @labels["azure_region"] = ENV["REGION_NAME"]
168
+ end
169
+
170
+ return unless @labels.key? "function_name"
171
+
172
+ @labels["rookout_serverless"] = "true"
82
173
  end
83
174
  end
84
175
  end