skylight 3.1.4 → 5.3.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +465 -294
- data/CLA.md +1 -1
- data/CONTRIBUTING.md +11 -3
- data/ERRORS.md +3 -0
- data/LICENSE.md +8 -18
- data/README.md +1 -2
- data/bin/skylight +1 -1
- data/ext/extconf.rb +118 -122
- data/ext/libskylight.yml +8 -6
- data/ext/skylight_native.c +56 -100
- data/lib/skylight/api.rb +41 -27
- data/lib/skylight/cli/doctor.rb +68 -70
- data/lib/skylight/cli/helpers.rb +3 -5
- data/lib/skylight/cli/merger.rb +99 -92
- data/lib/skylight/cli.rb +40 -43
- data/lib/skylight/config.rb +656 -201
- data/lib/skylight/data/cacert.pem +730 -1023
- data/lib/skylight/deprecation.rb +17 -0
- data/lib/skylight/errors.rb +34 -16
- data/lib/skylight/extensions/source_location.rb +291 -0
- data/lib/skylight/extensions.rb +95 -0
- data/lib/skylight/formatters/http.rb +18 -0
- data/lib/skylight/gc.rb +99 -0
- data/lib/skylight/helpers.rb +82 -39
- data/lib/skylight/instrumenter.rb +339 -9
- data/lib/skylight/middleware.rb +147 -1
- data/lib/skylight/native.rb +71 -23
- data/lib/skylight/native_ext_fetcher.rb +39 -47
- data/lib/skylight/normalizers/action_controller/process_action.rb +68 -0
- data/lib/skylight/normalizers/action_controller/send_file.rb +51 -0
- data/lib/skylight/normalizers/action_dispatch/process_middleware.rb +22 -0
- data/lib/skylight/normalizers/action_dispatch/route_set.rb +27 -0
- data/lib/skylight/normalizers/action_view/render_collection.rb +24 -0
- data/lib/skylight/normalizers/action_view/render_layout.rb +25 -0
- data/lib/skylight/normalizers/action_view/render_partial.rb +23 -0
- data/lib/skylight/normalizers/action_view/render_template.rb +23 -0
- data/lib/skylight/normalizers/active_job/perform.rb +87 -0
- data/lib/skylight/normalizers/active_model_serializers/render.rb +32 -0
- data/lib/skylight/normalizers/active_record/instantiation.rb +16 -0
- data/lib/skylight/normalizers/active_record/sql.rb +20 -0
- data/lib/skylight/normalizers/active_storage.rb +28 -0
- data/lib/skylight/normalizers/active_support/cache.rb +11 -0
- data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
- data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
- data/lib/skylight/normalizers/coach/handler_finish.rb +44 -0
- data/lib/skylight/normalizers/coach/middleware_finish.rb +33 -0
- data/lib/skylight/normalizers/couch_potato/query.rb +20 -0
- data/lib/skylight/normalizers/data_mapper/sql.rb +12 -0
- data/lib/skylight/normalizers/default.rb +24 -0
- data/lib/skylight/normalizers/elasticsearch/request.rb +20 -0
- data/lib/skylight/normalizers/faraday/request.rb +38 -0
- data/lib/skylight/normalizers/grape/endpoint.rb +28 -0
- data/lib/skylight/normalizers/grape/endpoint_render.rb +25 -0
- data/lib/skylight/normalizers/grape/endpoint_run.rb +39 -0
- data/lib/skylight/normalizers/grape/endpoint_run_filters.rb +20 -0
- data/lib/skylight/normalizers/grape/format_response.rb +20 -0
- data/lib/skylight/normalizers/graphiti/render.rb +22 -0
- data/lib/skylight/normalizers/graphiti/resolve.rb +31 -0
- data/lib/skylight/normalizers/graphql/base.rb +127 -0
- data/lib/skylight/normalizers/render.rb +79 -0
- data/lib/skylight/normalizers/sequel/sql.rb +12 -0
- data/lib/skylight/normalizers/shrine.rb +32 -0
- data/lib/skylight/normalizers/sql.rb +41 -0
- data/lib/skylight/normalizers.rb +157 -0
- data/lib/skylight/probes/action_controller.rb +52 -0
- data/lib/skylight/probes/action_dispatch/request_id.rb +33 -0
- data/lib/skylight/probes/action_dispatch/routing/route_set.rb +30 -0
- data/lib/skylight/probes/action_dispatch.rb +2 -0
- data/lib/skylight/probes/action_view.rb +42 -0
- data/lib/skylight/probes/active_job.rb +27 -0
- data/lib/skylight/probes/active_job_enqueue.rb +35 -0
- data/lib/skylight/probes/active_model_serializers.rb +50 -0
- data/lib/skylight/probes/active_record_async.rb +96 -0
- data/lib/skylight/probes/delayed_job.rb +144 -0
- data/lib/skylight/probes/elasticsearch.rb +45 -0
- data/lib/skylight/probes/excon/middleware.rb +65 -0
- data/lib/skylight/probes/excon.rb +25 -0
- data/lib/skylight/probes/faraday.rb +23 -0
- data/lib/skylight/probes/graphql.rb +38 -0
- data/lib/skylight/probes/httpclient.rb +44 -0
- data/lib/skylight/probes/middleware.rb +135 -0
- data/lib/skylight/probes/mongo.rb +169 -0
- data/lib/skylight/probes/mongoid.rb +6 -0
- data/lib/skylight/probes/net_http.rb +54 -0
- data/lib/skylight/probes/rack_builder.rb +37 -0
- data/lib/skylight/probes/redis.rb +68 -0
- data/lib/skylight/probes/sequel.rb +29 -0
- data/lib/skylight/probes/sinatra.rb +66 -0
- data/lib/skylight/probes/sinatra_add_middleware.rb +10 -10
- data/lib/skylight/probes/tilt.rb +25 -0
- data/lib/skylight/probes.rb +172 -0
- data/lib/skylight/railtie.rb +172 -15
- data/lib/skylight/sidekiq.rb +47 -0
- data/lib/skylight/sinatra.rb +2 -2
- data/lib/skylight/subscriber.rb +130 -0
- data/lib/skylight/test.rb +147 -0
- data/lib/skylight/trace.rb +331 -15
- data/lib/skylight/user_config.rb +60 -0
- data/lib/skylight/util/allocation_free.rb +26 -0
- data/lib/skylight/util/clock.rb +57 -0
- data/lib/skylight/util/component.rb +47 -9
- data/lib/skylight/util/deploy.rb +24 -40
- data/lib/skylight/util/gzip.rb +20 -0
- data/lib/skylight/util/hostname.rb +4 -4
- data/lib/skylight/util/http.rb +62 -71
- data/lib/skylight/util/instrumenter_method.rb +26 -0
- data/lib/skylight/util/logging.rb +136 -0
- data/lib/skylight/util/lru_cache.rb +36 -0
- data/lib/skylight/util/platform.rb +74 -0
- data/lib/skylight/util/proxy.rb +13 -0
- data/lib/skylight/util/ssl.rb +4 -28
- data/lib/skylight/util.rb +12 -0
- data/lib/skylight/vendor/cli/thor/rake_compat.rb +1 -1
- data/lib/skylight/version.rb +5 -1
- data/lib/skylight/vm/gc.rb +60 -0
- data/lib/skylight.rb +213 -24
- metadata +171 -53
data/lib/skylight/config.rb
CHANGED
|
@@ -1,190 +1,345 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
require
|
|
6
|
-
require
|
|
1
|
+
require "openssl"
|
|
2
|
+
require "yaml"
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "erb"
|
|
5
|
+
require "json"
|
|
6
|
+
require "skylight/util/logging"
|
|
7
|
+
require "skylight/util/proxy"
|
|
8
|
+
require "skylight/errors"
|
|
9
|
+
require "skylight/util/component"
|
|
10
|
+
require "skylight/util/deploy"
|
|
11
|
+
require "skylight/util/platform"
|
|
12
|
+
require "skylight/util/hostname"
|
|
13
|
+
require "skylight/util/ssl"
|
|
7
14
|
|
|
8
15
|
module Skylight
|
|
9
|
-
class Config
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
16
|
+
class Config
|
|
17
|
+
include Util::Logging
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
MUTEX = Mutex.new
|
|
21
|
+
|
|
22
|
+
# Map environment variable keys with Skylight configuration keys
|
|
23
|
+
ENV_TO_KEY = {
|
|
24
|
+
# == Authentication ==
|
|
25
|
+
-"AUTHENTICATION" => :authentication,
|
|
26
|
+
# == App settings ==
|
|
27
|
+
-"ROOT" => :root,
|
|
28
|
+
-"HOSTNAME" => :hostname,
|
|
29
|
+
-"SESSION_TOKEN" => :session_token,
|
|
30
|
+
# == Component settings ==
|
|
31
|
+
-"ENV" => :env,
|
|
32
|
+
-"COMPONENT" => :component,
|
|
33
|
+
-"REPORT_RAILS_ENV" => :report_rails_env,
|
|
34
|
+
# == Deploy settings ==
|
|
35
|
+
-"DEPLOY_ID" => :"deploy.id",
|
|
36
|
+
-"DEPLOY_GIT_SHA" => :"deploy.git_sha",
|
|
37
|
+
-"DEPLOY_DESCRIPTION" => :"deploy.description",
|
|
38
|
+
# == Logging ==
|
|
39
|
+
-"LOG_FILE" => :log_file,
|
|
40
|
+
-"LOG_LEVEL" => :log_level,
|
|
41
|
+
-"ALERT_LOG_FILE" => :alert_log_file,
|
|
42
|
+
-"NATIVE_LOG_FILE" => :native_log_file,
|
|
43
|
+
-"NATIVE_LOG_LEVEL" => :native_log_level,
|
|
44
|
+
-"LOG_SQL_PARSE_ERRORS" => :log_sql_parse_errors,
|
|
45
|
+
# == Proxy ==
|
|
46
|
+
-"PROXY_URL" => :proxy_url,
|
|
47
|
+
# == Instrumenter ==
|
|
48
|
+
-"ENABLE_SEGMENTS" => :enable_segments,
|
|
49
|
+
-"ENABLE_SIDEKIQ" => :enable_sidekiq,
|
|
50
|
+
-"IGNORED_ENDPOINT" => :ignored_endpoint,
|
|
51
|
+
-"IGNORED_ENDPOINTS" => :ignored_endpoints,
|
|
52
|
+
-"SINATRA_ROUTE_PREFIXES" => :sinatra_route_prefixes,
|
|
53
|
+
-"ENABLE_SOURCE_LOCATIONS" => :enable_source_locations,
|
|
54
|
+
# == Max Span Handling ==
|
|
55
|
+
-"REPORT_MAX_SPANS_EXCEEDED" => :report_max_spans_exceeded,
|
|
56
|
+
-"PRUNE_LARGE_TRACES" => :prune_large_traces,
|
|
57
|
+
# == Skylight Remote ==
|
|
58
|
+
-"AUTH_URL" => :auth_url,
|
|
59
|
+
-"APP_CREATE_URL" => :app_create_url,
|
|
60
|
+
-"MERGES_URL" => :merges_url,
|
|
61
|
+
-"VALIDATION_URL" => :validation_url,
|
|
62
|
+
-"AUTH_HTTP_DEFLATE" => :auth_http_deflate,
|
|
63
|
+
-"AUTH_HTTP_CONNECT_TIMEOUT" => :auth_http_connect_timeout,
|
|
64
|
+
-"AUTH_HTTP_READ_TIMEOUT" => :auth_http_read_timeout,
|
|
65
|
+
-"REPORT_URL" => :report_url,
|
|
66
|
+
-"REPORT_HTTP_DEFLATE" => :report_http_deflate,
|
|
67
|
+
-"REPORT_HTTP_CONNECT_TIMEOUT" => :report_http_connect_timeout,
|
|
68
|
+
-"REPORT_HTTP_READ_TIMEOUT" => :report_http_read_timeout,
|
|
69
|
+
-"REPORT_HTTP_DISABLED" => :report_http_disabled,
|
|
70
|
+
-"REPORT_USE_GRPC" => :report_use_grpc,
|
|
71
|
+
-"REPORT_GRPC_URL" => :report_grpc_url,
|
|
72
|
+
# == Native agent settings ==
|
|
73
|
+
#
|
|
74
|
+
-"LAZY_START" => :"daemon.lazy_start",
|
|
75
|
+
-"DAEMON_EXEC_PATH" => :"daemon.exec_path",
|
|
76
|
+
-"DAEMON_LIB_PATH" => :"daemon.lib_path",
|
|
77
|
+
-"PIDFILE_PATH" => :"daemon.pidfile_path",
|
|
78
|
+
-"SOCKDIR_PATH" => :"daemon.sockdir_path",
|
|
79
|
+
-"BATCH_QUEUE_DEPTH" => :"daemon.batch_queue_depth",
|
|
80
|
+
-"BATCH_SAMPLE_SIZE" => :"daemon.batch_sample_size",
|
|
81
|
+
-"BATCH_FLUSH_INTERVAL" => :"daemon.batch_flush_interval",
|
|
82
|
+
-"DAEMON_TICK_INTERVAL" => :"daemon.tick_interval",
|
|
83
|
+
-"DAEMON_LOCK_CHECK_INTERVAL" => :"daemon.lock_check_interval",
|
|
84
|
+
-"DAEMON_INACTIVITY_TIMEOUT" => :"daemon.inactivity_timeout",
|
|
85
|
+
-"CLIENT_MAX_TRIES" => :"daemon.max_connect_tries",
|
|
86
|
+
-"CLIENT_CONN_TRY_WIN" => :"daemon.connect_try_window",
|
|
87
|
+
-"MAX_PRESPAWN_JITTER" => :"daemon.max_prespawn_jitter",
|
|
88
|
+
-"DAEMON_WAIT_TIMEOUT" => :"daemon.wait_timeout",
|
|
89
|
+
-"CLIENT_CHECK_INTERVAL" => :"daemon.client_check_interval",
|
|
90
|
+
-"CLIENT_QUEUE_DEPTH" => :"daemon.client_queue_depth",
|
|
91
|
+
-"CLIENT_WRITE_TIMEOUT" => :"daemon.client_write_timeout",
|
|
92
|
+
-"SSL_CERT_PATH" => :"daemon.ssl_cert_path",
|
|
93
|
+
-"ENABLE_TCP" => :"daemon.enable_tcp",
|
|
94
|
+
-"TCP_PORT" => :"daemon.tcp_port",
|
|
95
|
+
# == Legacy env vars ==
|
|
96
|
+
#
|
|
97
|
+
-"AGENT_LOCKFILE" => :"agent.lockfile",
|
|
98
|
+
-"AGENT_SOCKFILE_PATH" => :"agent.sockfile_path",
|
|
99
|
+
# == User config settings ==
|
|
100
|
+
-"USER_CONFIG_PATH" => :user_config_path,
|
|
101
|
+
# == Heroku settings ==
|
|
102
|
+
-"HEROKU_DYNO_INFO_PATH" => :"heroku.dyno_info_path",
|
|
103
|
+
# == Source Location ==
|
|
104
|
+
-"SOURCE_LOCATION_IGNORED_GEMS" => :source_location_ignored_gems,
|
|
105
|
+
-"SOURCE_LOCATION_CACHE_SIZE" => :source_location_cache_size
|
|
106
|
+
}.freeze
|
|
107
|
+
|
|
108
|
+
KEY_TO_NATIVE_ENV = {
|
|
109
|
+
# We use different log files for native and Ruby, but the native code doesn't know this
|
|
110
|
+
native_log_file: "LOG_FILE",
|
|
111
|
+
native_log_level: "LOG_LEVEL"
|
|
112
|
+
}.freeze
|
|
113
|
+
|
|
114
|
+
SERVER_VALIDATE = %i[].freeze
|
|
115
|
+
|
|
116
|
+
DEFAULT_IGNORED_SOURCE_LOCATION_GEMS = [-"skylight", -"activesupport", -"activerecord"].freeze
|
|
82
117
|
|
|
83
118
|
# Default values for Skylight configuration keys
|
|
84
119
|
def self.default_values
|
|
85
|
-
@default_values ||=
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
120
|
+
@default_values ||=
|
|
121
|
+
begin
|
|
122
|
+
ret = {
|
|
123
|
+
# URLs
|
|
124
|
+
auth_url: -"https://auth.skylight.io/agent",
|
|
125
|
+
app_create_url: -"https://www.skylight.io/apps",
|
|
126
|
+
merges_url: -"https://www.skylight.io/merges",
|
|
127
|
+
validation_url: -"https://auth.skylight.io/agent/config",
|
|
128
|
+
# Logging
|
|
129
|
+
log_file: -"-",
|
|
130
|
+
log_level: -"INFO",
|
|
131
|
+
alert_log_file: -"-",
|
|
132
|
+
log_sql_parse_errors: true,
|
|
133
|
+
native_log_level: -"warn",
|
|
134
|
+
# Features
|
|
135
|
+
enable_segments: true,
|
|
136
|
+
enable_sidekiq: false,
|
|
137
|
+
sinatra_route_prefixes: false,
|
|
138
|
+
enable_source_locations: true,
|
|
139
|
+
# Deploys
|
|
140
|
+
"heroku.dyno_info_path": -"/etc/heroku/dyno",
|
|
141
|
+
report_rails_env: true,
|
|
142
|
+
# Daemon
|
|
143
|
+
"daemon.lazy_start": true,
|
|
144
|
+
hostname: Util::Hostname.default_hostname,
|
|
145
|
+
report_max_spans_exceeded: false,
|
|
146
|
+
prune_large_traces: true
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
ret[:"daemon.ssl_cert_path"] = Util::SSL.ca_cert_file_or_default unless Util::Platform::OS == -"darwin"
|
|
150
|
+
|
|
151
|
+
if Skylight.native?
|
|
152
|
+
native_path = Skylight.libskylight_path
|
|
153
|
+
|
|
154
|
+
ret[:"daemon.lib_path"] = native_path
|
|
155
|
+
ret[:"daemon.exec_path"] = File.join(native_path, "skylightd")
|
|
156
|
+
end
|
|
105
157
|
|
|
106
|
-
ret
|
|
107
|
-
ret[:'daemon.exec_path'] = File.join(native_path, 'skylightd')
|
|
158
|
+
ret
|
|
108
159
|
end
|
|
109
|
-
|
|
110
|
-
ret
|
|
111
|
-
end
|
|
112
160
|
end
|
|
113
161
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
end
|
|
162
|
+
REQUIRED_KEYS = {
|
|
163
|
+
authentication: "authentication token",
|
|
164
|
+
hostname: "server hostname",
|
|
165
|
+
auth_url: "authentication url",
|
|
166
|
+
validation_url: "config validation url"
|
|
167
|
+
}.freeze
|
|
122
168
|
|
|
123
169
|
def self.native_env_keys
|
|
124
|
-
@native_env_keys ||=
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
170
|
+
@native_env_keys ||=
|
|
171
|
+
%i[
|
|
172
|
+
native_log_level
|
|
173
|
+
native_log_file
|
|
174
|
+
log_sql_parse_errors
|
|
175
|
+
version
|
|
176
|
+
root
|
|
177
|
+
proxy_url
|
|
178
|
+
hostname
|
|
179
|
+
session_token
|
|
180
|
+
auth_url
|
|
181
|
+
auth_http_deflate
|
|
182
|
+
auth_http_connect_timeout
|
|
183
|
+
auth_http_read_timeout
|
|
184
|
+
report_url
|
|
185
|
+
report_http_deflate
|
|
186
|
+
report_http_connect_timeout
|
|
187
|
+
report_http_read_timeout
|
|
188
|
+
report_http_disabled
|
|
189
|
+
report_use_grpc
|
|
190
|
+
report_grpc_url
|
|
191
|
+
daemon.lazy_start
|
|
192
|
+
daemon.exec_path
|
|
193
|
+
daemon.lib_path
|
|
194
|
+
daemon.pidfile_path
|
|
195
|
+
daemon.sockdir_path
|
|
196
|
+
daemon.batch_queue_depth
|
|
197
|
+
daemon.batch_sample_size
|
|
198
|
+
daemon.batch_flush_interval
|
|
199
|
+
daemon.tick_interval
|
|
200
|
+
daemon.lock_check_interval
|
|
201
|
+
daemon.inactivity_timeout
|
|
202
|
+
daemon.max_connect_tries
|
|
203
|
+
daemon.connect_try_window
|
|
204
|
+
daemon.max_prespawn_jitter
|
|
205
|
+
daemon.wait_timeout
|
|
206
|
+
daemon.client_check_interval
|
|
207
|
+
daemon.client_queue_depth
|
|
208
|
+
daemon.client_write_timeout
|
|
209
|
+
daemon.ssl_cert_path
|
|
210
|
+
daemon.ssl_cert_dir
|
|
211
|
+
daemon.enable_tcp
|
|
212
|
+
daemon.tcp_port
|
|
213
|
+
]
|
|
159
214
|
end
|
|
160
215
|
|
|
216
|
+
# Maps legacy config keys to new config keys
|
|
161
217
|
def self.legacy_keys
|
|
162
|
-
@legacy_keys ||=
|
|
163
|
-
:'agent.sockfile_path' => :'daemon.sockdir_path',
|
|
164
|
-
:'agent.lockfile' => :'daemon.pidfile_path'
|
|
165
|
-
)
|
|
218
|
+
@legacy_keys ||= { "agent.sockfile_path": :"daemon.sockdir_path", "agent.lockfile": :"daemon.pidfile_path" }
|
|
166
219
|
end
|
|
167
220
|
|
|
168
221
|
def self.validators
|
|
169
|
-
@validators ||=
|
|
170
|
-
|
|
171
|
-
)
|
|
222
|
+
@validators ||=
|
|
223
|
+
{ "agent.interval": [->(v, _c) { v.is_a?(Integer) && v > 0 }, "must be an integer greater than 0"] }
|
|
172
224
|
end
|
|
173
225
|
|
|
174
226
|
# @api private
|
|
175
|
-
|
|
176
|
-
|
|
227
|
+
attr_reader :priority_key
|
|
228
|
+
|
|
229
|
+
# @api private
|
|
230
|
+
def initialize(*args)
|
|
231
|
+
attrs = {}
|
|
232
|
+
|
|
233
|
+
attrs = args.pop.dup if args.last.is_a?(Hash)
|
|
234
|
+
|
|
235
|
+
@values = {}
|
|
236
|
+
@priority = {}
|
|
237
|
+
@priority_regexp = nil
|
|
238
|
+
@alert_logger = nil
|
|
239
|
+
@logger = nil
|
|
240
|
+
|
|
241
|
+
p = attrs.delete(:priority)
|
|
242
|
+
|
|
243
|
+
if (@priority_key = args[0])
|
|
244
|
+
@priority_regexp = /^#{Regexp.escape(priority_key)}\.(.+)$/
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
attrs.each { |k, v| self[k] = v }
|
|
248
|
+
|
|
249
|
+
p&.each { |k, v| @priority[self.class.remap_key(k)] = v }
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def self.load(opts = {}, env = ENV)
|
|
253
|
+
attrs = {}
|
|
254
|
+
path = opts.delete(:file)
|
|
255
|
+
priority_key = opts.delete(:priority_key)
|
|
256
|
+
priority_key ||= opts[:env] # if a priority_key is not given, use env if available
|
|
257
|
+
|
|
258
|
+
if path
|
|
259
|
+
error = nil
|
|
260
|
+
begin
|
|
261
|
+
attrs =
|
|
262
|
+
YAML.safe_load(ERB.new(File.read(path)).result, permitted_classes: [], permitted_symbols: [], aliases: true)
|
|
263
|
+
error = "empty file" unless attrs
|
|
264
|
+
error = "invalid format" if attrs && !attrs.is_a?(Hash)
|
|
265
|
+
rescue Exception => e
|
|
266
|
+
error = e.message
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
raise ConfigError, "could not load config file; msg=#{error}" if error
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# The key-value pairs in this `priority` option are inserted into the
|
|
273
|
+
# config's @priority hash *after* anything listed under priority_key;
|
|
274
|
+
# i.e., ENV takes precendence over priority_key
|
|
275
|
+
attrs[:priority] = remap_env(env) if env
|
|
276
|
+
|
|
277
|
+
config = new(priority_key, attrs)
|
|
278
|
+
|
|
279
|
+
opts.each { |k, v| config[k] = v }
|
|
280
|
+
|
|
281
|
+
config
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def self.remap_key(key)
|
|
285
|
+
key = key.to_sym
|
|
286
|
+
legacy_keys[key] || key
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# @api private
|
|
290
|
+
def self.remap_env(env)
|
|
291
|
+
ret = {}
|
|
292
|
+
|
|
293
|
+
return ret unless env
|
|
294
|
+
|
|
295
|
+
# Only set if it exists, we don't want to set to a nil value
|
|
296
|
+
if (proxy_url = Util::Proxy.detect_url(env))
|
|
297
|
+
ret[:proxy_url] = proxy_url
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
env.each do |k, val|
|
|
301
|
+
next unless k =~ /^(?:SK|SKYLIGHT)_(.+)$/
|
|
302
|
+
next unless (key = ENV_TO_KEY[$1])
|
|
303
|
+
|
|
304
|
+
ret[key] =
|
|
305
|
+
case val
|
|
306
|
+
when /^false$/i
|
|
307
|
+
false
|
|
308
|
+
when /^true$/i
|
|
309
|
+
true
|
|
310
|
+
when /^(nil|null)$/i
|
|
311
|
+
nil
|
|
312
|
+
when /^\d+$/
|
|
313
|
+
val.to_i
|
|
314
|
+
when /^\d+\.\d+$/
|
|
315
|
+
val.to_f
|
|
316
|
+
else
|
|
317
|
+
val
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
ret
|
|
177
322
|
end
|
|
178
323
|
|
|
179
324
|
# @api private
|
|
180
325
|
def validate!
|
|
181
|
-
|
|
326
|
+
REQUIRED_KEYS.each { |k, v| raise ConfigError, "#{v} required" unless get(k) }
|
|
327
|
+
|
|
328
|
+
log_file = self[:log_file]
|
|
329
|
+
alert_log_file = self[:alert_log_file]
|
|
330
|
+
native_log_file = self.native_log_file
|
|
331
|
+
|
|
332
|
+
check_logfile_permissions(log_file, "log_file")
|
|
333
|
+
check_logfile_permissions(alert_log_file, "alert_log_file")
|
|
334
|
+
|
|
335
|
+
# TODO: Support rotation interpolation in this check
|
|
336
|
+
check_logfile_permissions(native_log_file, "native_log_file")
|
|
182
337
|
|
|
183
338
|
# TODO: Move this out of the validate! method: https://github.com/tildeio/direwolf-agent/issues/273
|
|
184
339
|
# FIXME: Why not set the sockdir_path and pidfile_path explicitly?
|
|
185
340
|
# That way we don't have to keep this in sync with the Rust repo.
|
|
186
|
-
sockdir_path = File.expand_path(self[:
|
|
187
|
-
pidfile_path = File.expand_path(self[:
|
|
341
|
+
sockdir_path = File.expand_path(self[:"daemon.sockdir_path"] || ".", root)
|
|
342
|
+
pidfile_path = File.expand_path(self[:"daemon.pidfile_path"] || "skylight.pid", sockdir_path)
|
|
188
343
|
|
|
189
344
|
check_file_permissions(pidfile_path, "daemon.pidfile_path or daemon.sockdir_path")
|
|
190
345
|
check_sockdir_permissions(sockdir_path)
|
|
@@ -192,6 +347,299 @@ module Skylight
|
|
|
192
347
|
true
|
|
193
348
|
end
|
|
194
349
|
|
|
350
|
+
def check_file_permissions(file, key)
|
|
351
|
+
file_root = File.dirname(file)
|
|
352
|
+
|
|
353
|
+
# Try to make the directory, don't blow up if we can't. Our writable? check will fail later.
|
|
354
|
+
begin
|
|
355
|
+
FileUtils.mkdir_p file_root
|
|
356
|
+
rescue StandardError
|
|
357
|
+
nil
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
if File.exist?(file) && !FileTest.writable?(file)
|
|
361
|
+
raise ConfigError, "File `#{file}` is not writable. Please set #{key} in your config to a writable path"
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
unless FileTest.writable?(file_root)
|
|
365
|
+
raise ConfigError,
|
|
366
|
+
"Directory `#{file_root}` is not writable. Please set #{key} in your config to a " \
|
|
367
|
+
"writable path"
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def check_logfile_permissions(log_file, key)
|
|
372
|
+
return if log_file == "-" # STDOUT
|
|
373
|
+
|
|
374
|
+
log_file = File.expand_path(log_file, root)
|
|
375
|
+
check_file_permissions(log_file, key)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
def key?(key)
|
|
379
|
+
key = self.class.remap_key(key)
|
|
380
|
+
@priority.key?(key) || @values.key?(key)
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
def get(key, default = nil)
|
|
384
|
+
key = self.class.remap_key(key)
|
|
385
|
+
|
|
386
|
+
return @priority[key] if @priority.key?(key)
|
|
387
|
+
return @values[key] if @values.key?(key)
|
|
388
|
+
return self.class.default_values[key] if self.class.default_values.key?(key)
|
|
389
|
+
|
|
390
|
+
if default
|
|
391
|
+
return default
|
|
392
|
+
elsif block_given?
|
|
393
|
+
return yield key
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
nil
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
alias [] get
|
|
400
|
+
|
|
401
|
+
def set(key, val, scope = nil)
|
|
402
|
+
key = [scope, key].join(".") if scope
|
|
403
|
+
|
|
404
|
+
if val.is_a?(Hash)
|
|
405
|
+
val.each { |k, v| set(k, v, key) }
|
|
406
|
+
else
|
|
407
|
+
k = self.class.remap_key(key)
|
|
408
|
+
|
|
409
|
+
if (validator = self.class.validators[k])
|
|
410
|
+
blk, msg = validator
|
|
411
|
+
|
|
412
|
+
unless blk.call(val, self)
|
|
413
|
+
error_msg = "invalid value for #{k} (#{val})"
|
|
414
|
+
error_msg << ", #{msg}" if msg
|
|
415
|
+
raise ConfigError, error_msg
|
|
416
|
+
end
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
@priority[$1.to_sym] = val if @priority_regexp && k =~ @priority_regexp
|
|
420
|
+
|
|
421
|
+
@values[k] = val
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
alias []= set
|
|
426
|
+
|
|
427
|
+
def send_or_get(val)
|
|
428
|
+
respond_to?(val) ? send(val) : get(val)
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
def duration_ms(key, default = nil)
|
|
432
|
+
if (v = self[key]) && v.to_s =~ /^\s*(\d+)(s|sec|ms|micros|nanos)?\s*$/
|
|
433
|
+
v = $1.to_i
|
|
434
|
+
case $2
|
|
435
|
+
when "ms"
|
|
436
|
+
v
|
|
437
|
+
when "micros"
|
|
438
|
+
v / 1_000
|
|
439
|
+
when "nanos"
|
|
440
|
+
v / 1_000_000
|
|
441
|
+
else
|
|
442
|
+
# "s", "sec", nil
|
|
443
|
+
v * 1000
|
|
444
|
+
end
|
|
445
|
+
else
|
|
446
|
+
default
|
|
447
|
+
end
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def to_native_env
|
|
451
|
+
ret = []
|
|
452
|
+
|
|
453
|
+
self
|
|
454
|
+
.class
|
|
455
|
+
.native_env_keys
|
|
456
|
+
.each do |key|
|
|
457
|
+
value = send_or_get(key)
|
|
458
|
+
unless value.nil?
|
|
459
|
+
env_key = KEY_TO_NATIVE_ENV[key] || ENV_TO_KEY.key(key) || key.upcase
|
|
460
|
+
ret << "SKYLIGHT_#{env_key}" << cast_for_env(value)
|
|
461
|
+
end
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
ret << "SKYLIGHT_AUTHENTICATION" << authentication_with_meta
|
|
465
|
+
ret << "SKYLIGHT_VALIDATE_AUTHENTICATION" << "false"
|
|
466
|
+
|
|
467
|
+
ret
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
#
|
|
471
|
+
#
|
|
472
|
+
# ===== Helpers =====
|
|
473
|
+
#
|
|
474
|
+
#
|
|
475
|
+
|
|
476
|
+
def version
|
|
477
|
+
VERSION
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# @api private
|
|
481
|
+
def gc
|
|
482
|
+
@gc ||= GC.new(self, get("gc.profiler", VM::GC.new))
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# @api private
|
|
486
|
+
def ignored_endpoints
|
|
487
|
+
@ignored_endpoints ||=
|
|
488
|
+
begin
|
|
489
|
+
ignored_endpoints = get(:ignored_endpoints)
|
|
490
|
+
|
|
491
|
+
# If, for some odd reason you have a comma in your endpoint name, use the
|
|
492
|
+
# YML config instead.
|
|
493
|
+
ignored_endpoints = ignored_endpoints.split(/\s*,\s*/) if ignored_endpoints.is_a?(String)
|
|
494
|
+
|
|
495
|
+
val = Array(get(:ignored_endpoint))
|
|
496
|
+
val.concat(Array(ignored_endpoints))
|
|
497
|
+
val
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
# @api private
|
|
502
|
+
def source_location_ignored_gems
|
|
503
|
+
@source_location_ignored_gems ||=
|
|
504
|
+
begin
|
|
505
|
+
ignored_gems = get(:source_location_ignored_gems)
|
|
506
|
+
ignored_gems = ignored_gems.split(/\s*,\s*/) if ignored_gems.is_a?(String)
|
|
507
|
+
|
|
508
|
+
Array(ignored_gems) | DEFAULT_IGNORED_SOURCE_LOCATION_GEMS
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def root
|
|
513
|
+
@root ||= Pathname.new(self[:root] || Dir.pwd).realpath
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def log_level
|
|
517
|
+
@log_level ||=
|
|
518
|
+
if trace?
|
|
519
|
+
Logger::DEBUG
|
|
520
|
+
else
|
|
521
|
+
case get(:log_level)
|
|
522
|
+
when /^debug$/i
|
|
523
|
+
Logger::DEBUG
|
|
524
|
+
when /^info$/i
|
|
525
|
+
Logger::INFO
|
|
526
|
+
when /^warn$/i
|
|
527
|
+
Logger::WARN
|
|
528
|
+
when /^error$/i
|
|
529
|
+
Logger::ERROR
|
|
530
|
+
when /^fatal$/i
|
|
531
|
+
Logger::FATAL
|
|
532
|
+
else
|
|
533
|
+
Logger::ERROR
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
def native_log_level
|
|
539
|
+
get(:native_log_level).to_s.downcase
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def logger
|
|
543
|
+
@logger ||= MUTEX.synchronize { load_logger }
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
def native_log_file
|
|
547
|
+
@native_log_file ||=
|
|
548
|
+
get("native_log_file") do
|
|
549
|
+
log_file = self["log_file"]
|
|
550
|
+
return "-" if log_file == "-"
|
|
551
|
+
|
|
552
|
+
parts = log_file.to_s.split(".")
|
|
553
|
+
parts.insert(-2, "native")
|
|
554
|
+
parts.join(".")
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
attr_writer :logger, :alert_logger
|
|
559
|
+
|
|
560
|
+
def alert_logger
|
|
561
|
+
@alert_logger ||=
|
|
562
|
+
MUTEX.synchronize do
|
|
563
|
+
unless (l = @alert_logger)
|
|
564
|
+
out = get(:alert_log_file)
|
|
565
|
+
out = Util::AlertLogger.new(load_logger) if out == "-"
|
|
566
|
+
|
|
567
|
+
l = create_logger(out, level: Logger::DEBUG)
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
l
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
def enable_segments?
|
|
575
|
+
!!get(:enable_segments)
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
def enable_sidekiq?
|
|
579
|
+
!!get(:enable_sidekiq)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def sinatra_route_prefixes?
|
|
583
|
+
!!get(:sinatra_route_prefixes)
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def enable_source_locations?
|
|
587
|
+
!!get(:enable_source_locations)
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
def user_config
|
|
591
|
+
@user_config ||= UserConfig.new(self)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def on_heroku?
|
|
595
|
+
File.exist?(get(:"heroku.dyno_info_path"))
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
private
|
|
599
|
+
|
|
600
|
+
def create_logger(out, level: :info)
|
|
601
|
+
if out.is_a?(String)
|
|
602
|
+
out = File.expand_path(out, root)
|
|
603
|
+
|
|
604
|
+
# May be redundant since we also do this in the permissions check
|
|
605
|
+
FileUtils.mkdir_p(File.dirname(out))
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
Logger.new(out, progname: "Skylight", level: level)
|
|
609
|
+
rescue StandardError
|
|
610
|
+
Logger.new($stdout, progname: "Skylight", level: level)
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
def load_logger
|
|
614
|
+
unless (l = @logger)
|
|
615
|
+
out = get(:log_file)
|
|
616
|
+
out = $stdout if out == "-"
|
|
617
|
+
l = create_logger(out, level: log_level)
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
l
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
def cast_for_env(val)
|
|
624
|
+
case val
|
|
625
|
+
when true
|
|
626
|
+
"true"
|
|
627
|
+
when false
|
|
628
|
+
"false"
|
|
629
|
+
when nil
|
|
630
|
+
"nil"
|
|
631
|
+
else
|
|
632
|
+
val.to_s
|
|
633
|
+
end
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
public
|
|
637
|
+
|
|
638
|
+
# @api private
|
|
639
|
+
def api
|
|
640
|
+
@api ||= Api.new(self)
|
|
641
|
+
end
|
|
642
|
+
|
|
195
643
|
def validate_with_server
|
|
196
644
|
res = api.validate_config
|
|
197
645
|
|
|
@@ -200,74 +648,66 @@ module Skylight
|
|
|
200
648
|
return false
|
|
201
649
|
end
|
|
202
650
|
|
|
203
|
-
if res.
|
|
204
|
-
warn("Unable to reach server for config validation")
|
|
205
|
-
end
|
|
651
|
+
warn("Unable to reach server for config validation") if res.error_response?
|
|
206
652
|
|
|
207
653
|
unless res.config_valid?
|
|
208
|
-
warn("Invalid configuration") unless res.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
end
|
|
213
|
-
end
|
|
654
|
+
warn("Invalid configuration") unless res.error_response?
|
|
655
|
+
res.validation_errors.each { |k, v| warn(" #{k}: #{v}") }
|
|
656
|
+
|
|
657
|
+
return false if res.forbidden?
|
|
214
658
|
|
|
215
659
|
corrected_config = res.corrected_config
|
|
216
|
-
unless corrected_config
|
|
217
|
-
# Use defaults if no corrected config is available. This will happen if the request failed.
|
|
218
|
-
corrected_config = Hash[self.class.server_validated_keys.map{|k| [k, [k]] }]
|
|
219
|
-
end
|
|
220
660
|
|
|
221
|
-
|
|
661
|
+
# Use defaults if no corrected config is available. This will happen if the request failed.
|
|
662
|
+
corrected_config ||= SERVER_VALIDATE.to_h { |k| [k, self.class.default_values.fetch(k)] }
|
|
663
|
+
|
|
664
|
+
config_to_update = corrected_config.reject { |k, v| get(k) == v }
|
|
222
665
|
unless config_to_update.empty?
|
|
223
666
|
info("Updating config values:")
|
|
224
|
-
config_to_update.each do |k,v|
|
|
667
|
+
config_to_update.each do |k, v|
|
|
225
668
|
info(" setting #{k} to #{v}")
|
|
226
669
|
|
|
227
670
|
# This is a weird way to handle priorities
|
|
228
671
|
# See https://github.com/tildeio/direwolf-agent/issues/275
|
|
229
|
-
k = "#{
|
|
672
|
+
k = "#{priority_key}.#{k}" if priority_key
|
|
230
673
|
|
|
231
674
|
set(k, v)
|
|
232
675
|
end
|
|
233
676
|
end
|
|
234
677
|
end
|
|
235
678
|
|
|
236
|
-
|
|
679
|
+
true
|
|
237
680
|
end
|
|
238
681
|
|
|
239
682
|
def check_sockdir_permissions(sockdir_path)
|
|
240
683
|
# Try to make the directory, don't blow up if we can't. Our writable? check will fail later.
|
|
241
|
-
|
|
684
|
+
begin
|
|
685
|
+
FileUtils.mkdir_p sockdir_path
|
|
686
|
+
rescue StandardError
|
|
687
|
+
nil
|
|
688
|
+
end
|
|
242
689
|
|
|
243
690
|
unless FileTest.writable?(sockdir_path)
|
|
244
|
-
raise
|
|
691
|
+
raise ConfigError,
|
|
692
|
+
"Directory `#{sockdir_path}` is not writable. Please set daemon.sockdir_path in " \
|
|
693
|
+
"your config to a writable path"
|
|
245
694
|
end
|
|
246
695
|
|
|
247
696
|
if check_nfs(sockdir_path)
|
|
248
|
-
raise
|
|
697
|
+
raise ConfigError,
|
|
698
|
+
"Directory `#{sockdir_path}` is an NFS mount and will not allow sockets. Please set " \
|
|
699
|
+
"daemon.sockdir_path in your config to a non-NFS path."
|
|
249
700
|
end
|
|
250
701
|
end
|
|
251
702
|
|
|
252
|
-
def to_native_env
|
|
253
|
-
ret = super
|
|
254
|
-
|
|
255
|
-
ret << "SKYLIGHT_AUTHENTICATION" << authentication_with_meta
|
|
256
|
-
ret << "SKYLIGHT_VALIDATE_AUTHENTICATION" << "false"
|
|
257
|
-
|
|
258
|
-
ret
|
|
259
|
-
end
|
|
260
|
-
|
|
261
703
|
def write(path)
|
|
262
704
|
FileUtils.mkdir_p(File.dirname(path))
|
|
263
705
|
|
|
264
|
-
File.open(path,
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
#
|
|
268
|
-
authentication: #{self[:authentication]}
|
|
706
|
+
File.open(path, "w") { |f| f.puts <<~YAML }
|
|
707
|
+
---
|
|
708
|
+
# The authentication token for the application.
|
|
709
|
+
authentication: #{self[:authentication]}
|
|
269
710
|
YAML
|
|
270
|
-
end
|
|
271
711
|
end
|
|
272
712
|
|
|
273
713
|
#
|
|
@@ -280,9 +720,8 @@ authentication: #{self[:authentication]}
|
|
|
280
720
|
token = get(:authentication)
|
|
281
721
|
|
|
282
722
|
if token
|
|
283
|
-
meta = {
|
|
723
|
+
meta = {}
|
|
284
724
|
meta.merge!(deploy.to_query_hash) if deploy
|
|
285
|
-
meta[:component] = component.to_s if component
|
|
286
725
|
meta[:reporting_env] = true if reporting_env?
|
|
287
726
|
|
|
288
727
|
# A pipe should be a safe delimiter since it's not in the standard token
|
|
@@ -297,17 +736,33 @@ authentication: #{self[:authentication]}
|
|
|
297
736
|
@deploy ||= Util::Deploy.build(self)
|
|
298
737
|
end
|
|
299
738
|
|
|
300
|
-
def
|
|
301
|
-
@
|
|
739
|
+
def components
|
|
740
|
+
@components ||=
|
|
741
|
+
{
|
|
742
|
+
web: Util::Component.new(get(:env), Util::Component::DEFAULT_NAME),
|
|
743
|
+
worker: Util::Component.new(get(:env), get(:component) || get(:worker_component), force_worker: true)
|
|
744
|
+
}
|
|
302
745
|
rescue ArgumentError => e
|
|
303
|
-
raise
|
|
746
|
+
raise ConfigError, e.message
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
def component
|
|
750
|
+
components[:web]
|
|
751
|
+
end
|
|
752
|
+
|
|
753
|
+
def to_json(*)
|
|
754
|
+
JSON.generate(as_json)
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
def as_json(*)
|
|
758
|
+
{ config: { priority: @priority.merge(component.as_json), values: @values } }
|
|
304
759
|
end
|
|
305
760
|
|
|
306
|
-
|
|
761
|
+
private
|
|
307
762
|
|
|
308
763
|
def check_nfs(path)
|
|
309
764
|
# Should work on most *nix, though not on OS X
|
|
310
|
-
`stat -f -L -c %T #{path} 2>&1`.strip ==
|
|
765
|
+
`stat -f -L -c %T #{path} 2>&1`.strip == "nfs"
|
|
311
766
|
end
|
|
312
767
|
|
|
313
768
|
def reporting_env?
|