smart_proxy_dynflow_core 0.2.6 → 0.3.0
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/Gemfile +6 -20
- data/config/settings.yml.example +19 -3
- data/lib/smart_proxy_dynflow_core.rb +3 -2
- data/lib/smart_proxy_dynflow_core/api.rb +8 -0
- data/lib/smart_proxy_dynflow_core/bundler_helper.rb +0 -1
- data/lib/smart_proxy_dynflow_core/callback.rb +0 -1
- data/lib/smart_proxy_dynflow_core/core.rb +3 -1
- data/lib/smart_proxy_dynflow_core/launcher.rb +14 -15
- data/lib/smart_proxy_dynflow_core/log.rb +103 -43
- data/lib/smart_proxy_dynflow_core/logger_middleware.rb +31 -0
- data/lib/smart_proxy_dynflow_core/request_id_middleware.rb +18 -0
- data/lib/smart_proxy_dynflow_core/settings.rb +7 -25
- data/lib/smart_proxy_dynflow_core/version.rb +1 -1
- data/smart_proxy_dynflow_core.gemspec +4 -2
- metadata +38 -9
- data/lib/smart_proxy_dynflow_core/sd_notify.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 467f03a2c2c0ad4e3b168039abdb8e9a465a46b8ecf44aade57c5a09bbeafbfc
|
4
|
+
data.tar.gz: e966e14e4a95f42af61b5bcf47595ad6afa241271656b6724e5000b3e2cd354d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6a3b2b7b4dc313c1b6cc215c2de6cda4f49ad9f901bc7ab949b0ed4a16521e021b9c39a0fc371091e54172610787f968a2bb8577f68086ef15308bd805fc970
|
7
|
+
data.tar.gz: 7cbfc949016d5d824ebbb421093c8ef687c24d33c6699e7ef0c875145e035e8233317ff64c7757597bd0e76c9186566dec4e407397e32803b6d42ea26602fb6f
|
data/Gemfile
CHANGED
@@ -10,28 +10,14 @@ group :test do
|
|
10
10
|
gem 'smart_proxy', :git => "https://github.com/theforeman/smart-proxy", :branch => "develop"
|
11
11
|
gem 'smart_proxy_dynflow', :path => '.'
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
else
|
17
|
-
gem 'public_suffix'
|
18
|
-
gem 'rubocop', '~> 0.52.1'
|
19
|
-
end
|
20
|
-
|
21
|
-
if RUBY_VERSION < '2.2'
|
22
|
-
gem 'rack-test', '< 0.8'
|
23
|
-
else
|
24
|
-
gem 'rack-test'
|
25
|
-
end
|
13
|
+
gem 'public_suffix'
|
14
|
+
gem 'rack-test'
|
15
|
+
gem 'rubocop', '~> 0.52.1'
|
26
16
|
end
|
27
17
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
else
|
32
|
-
gem 'rack', '>= 1.1'
|
33
|
-
gem 'sinatra'
|
34
|
-
end
|
18
|
+
gem 'logging-journald', '~> 2.0', :platforms => [:ruby]
|
19
|
+
gem 'rack', '>= 1.1'
|
20
|
+
gem 'sinatra'
|
35
21
|
|
36
22
|
# load bundler.d
|
37
23
|
Dir["#{File.dirname(__FILE__)}/bundler.d/*.rb"].each do |bundle|
|
data/config/settings.yml.example
CHANGED
@@ -39,11 +39,27 @@
|
|
39
39
|
# Specify versions like: '1.1', or '1.2'
|
40
40
|
#:tls_disabled_versions: []
|
41
41
|
|
42
|
-
# File to log to, leave empty for
|
43
|
-
|
42
|
+
# File to log to, leave empty for stdout or use STDOUT, STDERR, SYSLOG or JOURNAL
|
43
|
+
#:log_file: /var/log/foreman-proxy/smart_proxy_dynflow_core.log
|
44
44
|
|
45
45
|
# Log level, one of UNKNOWN, FATAL, ERROR, WARN, INFO, DEBUG
|
46
|
-
|
46
|
+
#:log_level: ERROR
|
47
|
+
|
48
|
+
# The maximum size of a log file before it's rolled (in MiB) or zero to disable file rolling
|
49
|
+
# and rely on logrotate or similar tool
|
50
|
+
#:file_rolling_size: 0
|
51
|
+
|
52
|
+
# The maximum age of a log file before it's rolled (in seconds). Also accepts 'daily', 'weekly', or 'monthly'.
|
53
|
+
#:file_rolling_age: weekly
|
54
|
+
|
55
|
+
# Number of log files to keep
|
56
|
+
#:file_rolling_keep: 6
|
57
|
+
|
58
|
+
# Logging pattern for file-based loging
|
59
|
+
#:file_logging_pattern: '%d %.8X{request} [%.1l] %m'
|
60
|
+
|
61
|
+
# Logging pattern for syslog or journal loging
|
62
|
+
#:system_logging_pattern: '%.8X{request} [%.1l] %m'
|
47
63
|
|
48
64
|
# Maximum age of execution plans to keep before having them cleaned
|
49
65
|
# by the execution plan cleaner (in seconds), defaults to 24 hours
|
@@ -1,6 +1,7 @@
|
|
1
|
-
raise LoadError, 'Ruby >= 2.1 is required' unless RUBY_VERSION >= '2.1'
|
2
|
-
|
3
1
|
require 'dynflow'
|
2
|
+
require 'smart_proxy_dynflow_core/request_id_middleware'
|
3
|
+
require 'smart_proxy_dynflow_core/logger_middleware'
|
4
|
+
require 'smart_proxy_dynflow_core/middleware/keep_current_request_id'
|
4
5
|
require 'smart_proxy_dynflow_core/task_launcher_registry'
|
5
6
|
require 'foreman_tasks_core'
|
6
7
|
require 'smart_proxy_dynflow_core/log'
|
@@ -6,6 +6,14 @@ module SmartProxyDynflowCore
|
|
6
6
|
TASK_UPDATE_REGEXP_PATH = %r{/tasks/(\S+)/(update|done)}
|
7
7
|
helpers Helpers
|
8
8
|
|
9
|
+
configure do
|
10
|
+
if Settings.instance.standalone
|
11
|
+
::Sinatra::Base.set :logging, false
|
12
|
+
::Sinatra::Base.use ::SmartProxyDynflowCore::RequestIdMiddleware
|
13
|
+
::Sinatra::Base.use ::SmartProxyDynflowCore::LoggerMiddleware
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
9
17
|
before do
|
10
18
|
if match = request.path_info.match(TASK_UPDATE_REGEXP_PATH)
|
11
19
|
task_id = match[1]
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module SmartProxyDynflowCore
|
2
2
|
class BundlerHelper
|
3
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
4
3
|
def self.require_groups(*groups)
|
5
4
|
if File.exist?(File.expand_path('../../../Gemfile.in', __FILE__))
|
6
5
|
# If there is a Gemfile.in file, we will not use Bundler but BundlerExt
|
@@ -15,7 +15,9 @@ module SmartProxyDynflowCore
|
|
15
15
|
|
16
16
|
def create_world(&block)
|
17
17
|
config = default_world_config(&block)
|
18
|
-
::Dynflow::World.new(config)
|
18
|
+
world = ::Dynflow::World.new(config)
|
19
|
+
world.middleware.use ::Actions::Middleware::KeepCurrentRequestID
|
20
|
+
world
|
19
21
|
end
|
20
22
|
|
21
23
|
def persistence_conn_string
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'webrick/https'
|
2
2
|
require 'smart_proxy_dynflow_core/bundler_helper'
|
3
3
|
require 'smart_proxy_dynflow_core/settings'
|
4
|
-
require '
|
4
|
+
require 'sd_notify'
|
5
5
|
|
6
6
|
module SmartProxyDynflowCore
|
7
7
|
class Launcher
|
@@ -14,13 +14,15 @@ module SmartProxyDynflowCore
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def start(options)
|
17
|
-
load_settings!(options)
|
18
17
|
Settings.instance.standalone = true
|
18
|
+
load_settings!(options)
|
19
19
|
install_usr1_trap
|
20
20
|
Rack::Server.new(rack_settings).start do |_server|
|
21
21
|
SmartProxyDynflowCore::Core.ensure_initialized
|
22
|
-
|
22
|
+
::SdNotify.ready
|
23
23
|
end
|
24
|
+
Log.instance.info "Finished shutting down"
|
25
|
+
Logging.shutdown
|
24
26
|
end
|
25
27
|
|
26
28
|
def load_settings!(options = {})
|
@@ -53,7 +55,7 @@ module SmartProxyDynflowCore
|
|
53
55
|
|
54
56
|
def install_usr1_trap
|
55
57
|
trap(:USR1) do
|
56
|
-
Log.
|
58
|
+
Log.reopen
|
57
59
|
end
|
58
60
|
end
|
59
61
|
|
@@ -81,7 +83,7 @@ module SmartProxyDynflowCore
|
|
81
83
|
:app => app,
|
82
84
|
:Host => Settings.instance.listen,
|
83
85
|
:Port => Settings.instance.port,
|
84
|
-
:AccessLog => [
|
86
|
+
:AccessLog => [],
|
85
87
|
:Logger => Log.instance,
|
86
88
|
:daemonize => Settings.instance.daemonize,
|
87
89
|
:pid => Settings.instance.daemonize && Settings.instance.pid_file,
|
@@ -89,7 +91,6 @@ module SmartProxyDynflowCore
|
|
89
91
|
}
|
90
92
|
end
|
91
93
|
|
92
|
-
# rubocop:disable Metrics/PerceivedComplexity
|
93
94
|
def https_app
|
94
95
|
ssl_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS[:options]
|
95
96
|
ssl_options |= OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE if defined?(OpenSSL::SSL::OP_CIPHER_SERVER_PREFERENCE)
|
@@ -99,16 +100,14 @@ module SmartProxyDynflowCore
|
|
99
100
|
ssl_options |= OpenSSL::SSL::OP_NO_TLSv1 if defined?(OpenSSL::SSL::OP_NO_TLSv1)
|
100
101
|
ssl_options |= OpenSSL::SSL::OP_NO_TLSv1_1 if defined?(OpenSSL::SSL::OP_NO_TLSv1_1)
|
101
102
|
|
102
|
-
|
103
|
-
|
104
|
-
constant = OpenSSL::SSL.const_get("OP_NO_TLSv#{version.to_s.tr('.', '_')}") rescue nil
|
103
|
+
Settings.instance.tls_disabled_versions&.each do |version|
|
104
|
+
constant = OpenSSL::SSL.const_get("OP_NO_TLSv#{version.to_s.tr('.', '_')}") rescue nil
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
106
|
+
if constant
|
107
|
+
Log.instance.info "TLSv#{version} will be disabled."
|
108
|
+
ssl_options |= constant
|
109
|
+
else
|
110
|
+
Log.instance.warn "TLSv#{version} was not found."
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
@@ -1,61 +1,126 @@
|
|
1
|
-
require '
|
1
|
+
require 'logging'
|
2
2
|
|
3
3
|
module SmartProxyDynflowCore
|
4
|
-
class
|
5
|
-
|
4
|
+
class ReopenAppender < ::Logging::Appender
|
5
|
+
def initialize(name, logger, opts = {})
|
6
|
+
@reopen = false
|
7
|
+
@logger = logger
|
8
|
+
super(name, opts)
|
9
|
+
end
|
6
10
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@logger = self.new log_file
|
11
|
-
@logger.level = log_level
|
12
|
-
end
|
13
|
-
@logger
|
14
|
-
end
|
11
|
+
def set(status = true)
|
12
|
+
@reopen = status
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
15
|
+
def append(_event)
|
16
|
+
if @reopen
|
17
|
+
Logging.reopen
|
18
|
+
@reopen = false
|
18
19
|
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class Log
|
24
|
+
BASE_LOG_SIZE = 1024 * 1024 # 1 MiB
|
25
|
+
LOGGER_NAME = 'dynflow-core'.freeze
|
26
|
+
|
27
|
+
begin
|
28
|
+
require 'syslog/logger'
|
29
|
+
@syslog_available = true
|
30
|
+
rescue LoadError
|
31
|
+
@syslog_available = false
|
32
|
+
end
|
19
33
|
|
34
|
+
class << self
|
20
35
|
def reload!
|
36
|
+
Logging.logger[LOGGER_NAME].appenders.each(&:close)
|
37
|
+
Logging.logger[LOGGER_NAME].clear_appenders
|
21
38
|
@logger = nil
|
22
39
|
instance
|
23
40
|
end
|
24
41
|
|
25
|
-
def
|
26
|
-
if
|
27
|
-
|
28
|
-
|
29
|
-
Logger::WARN
|
42
|
+
def reopen
|
43
|
+
return if @logger.nil? || @reopen.nil?
|
44
|
+
if Settings.instance.log_file !~ /^(STDOUT|SYSLOG|JOURNALD?)$/i
|
45
|
+
@reopen.set
|
30
46
|
end
|
31
47
|
end
|
32
48
|
|
33
|
-
def
|
34
|
-
|
35
|
-
|
49
|
+
def instance
|
50
|
+
return ::Proxy::LogBuffer::Decorator.instance unless Settings.instance.standalone
|
51
|
+
return @logger if @logger
|
52
|
+
layout = Logging::Layouts.pattern(pattern: Settings.instance.file_logging_pattern + "\n")
|
53
|
+
notime_layout = Logging::Layouts.pattern(pattern: Settings.instance.system_logging_pattern + "\n")
|
54
|
+
log_file = Settings.instance.log_file || ''
|
55
|
+
@logger = Logging.logger[LOGGER_NAME]
|
56
|
+
@reopen = ReopenAppender.new("Reopen dummy appender", @logger)
|
57
|
+
@logger.add_appenders(@reopen)
|
58
|
+
if !Settings.instance.loaded || log_file.casecmp('STDOUT').zero?
|
59
|
+
@logger.add_appenders(Logging.appenders.stdout(LOGGER_NAME, layout: layout))
|
60
|
+
elsif log_file.casecmp('SYSLOG').zero?
|
61
|
+
unless @syslog_available
|
62
|
+
puts "Syslog is not supported on this platform, use STDOUT or a file"
|
63
|
+
exit(1)
|
64
|
+
end
|
65
|
+
@logger.add_appenders(Logging.appenders.syslog(LOGGER_NAME, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5))
|
66
|
+
elsif log_file.casecmp('JOURNAL').zero? || log_file.casecmp('JOURNALD').zero?
|
67
|
+
begin
|
68
|
+
@logger.add_appenders(Logging.appenders.journald(LOGGER_NAME, LOGGER_NAME: :proxy_logger, layout: notime_layout, facility: ::Syslog::Constants::LOG_LOCAL5))
|
69
|
+
rescue NoMethodError
|
70
|
+
@logger.add_appenders(Logging.appenders.stdout(LOGGER_NAME, layout: layout))
|
71
|
+
@logger.warn "Journald is not available on this platform. Falling back to STDOUT."
|
72
|
+
end
|
36
73
|
else
|
37
|
-
|
74
|
+
begin
|
75
|
+
keep = Settings.instance.file_rolling_keep
|
76
|
+
size = BASE_LOG_SIZE * Settings.instance.file_rolling_size
|
77
|
+
age = Settings.instance.file_rolling_age
|
78
|
+
if size.positive?
|
79
|
+
@logger.add_appenders(Logging.appenders.rolling_file(LOGGER_NAME, layout: layout, filename: log_file, keep: keep, size: size, age: age, roll_by: 'number'))
|
80
|
+
else
|
81
|
+
@logger.add_appenders(Logging.appenders.file(LOGGER_NAME, layout: layout, filename: log_file))
|
82
|
+
end
|
83
|
+
rescue ArgumentError => ae
|
84
|
+
@logger.add_appenders(Logging.appenders.stdout(LOGGER_NAME, layout: layout))
|
85
|
+
@logger.warn "Log file #{log_file} cannot be opened. Falling back to STDOUT: #{ae}"
|
86
|
+
end
|
38
87
|
end
|
88
|
+
@logger.level = ::Logging.level_num(Settings.instance.log_level)
|
89
|
+
@logger
|
39
90
|
end
|
40
|
-
end
|
41
91
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
92
|
+
def with_fields(fields = {})
|
93
|
+
::Logging.ndc.push(fields) do
|
94
|
+
yield
|
95
|
+
end
|
96
|
+
end
|
48
97
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
98
|
+
# Standard way for logging exceptions to get the most data in the log. By default
|
99
|
+
# it logs via warn level, this can be changed via options[:level]
|
100
|
+
def exception(context_message, exception, options = {})
|
101
|
+
level = options[:level] || :warn
|
102
|
+
unless ::Logging::LEVELS.keys.include?(level.to_s)
|
103
|
+
raise "Unexpected log level #{level}, expected one of #{::Logging::LEVELS.keys}"
|
104
|
+
end
|
105
|
+
# send class, message and stack as structured fields in addition to message string
|
106
|
+
backtrace = exception.backtrace ? exception.backtrace : []
|
107
|
+
extra_fields = {
|
108
|
+
exception_class: exception.class.name,
|
109
|
+
exception_message: exception.message,
|
110
|
+
exception_backtrace: backtrace
|
111
|
+
}
|
112
|
+
extra_fields[:foreman_code] = exception.code if exception.respond_to?(:code)
|
113
|
+
with_fields(extra_fields) do
|
114
|
+
@logger.public_send(level) do
|
115
|
+
([context_message, "#{exception.class}: #{exception.message}"] + backtrace).join("\n")
|
116
|
+
end
|
117
|
+
end
|
53
118
|
end
|
54
119
|
end
|
55
120
|
|
56
121
|
class ProxyStructuredFormater < ::Dynflow::LoggerAdapters::Formatters::Abstract
|
57
|
-
def
|
58
|
-
if message.is_a?(
|
122
|
+
def format(message)
|
123
|
+
if message.is_a?(Exception)
|
59
124
|
subject = "#{message.message} (#{message.class})"
|
60
125
|
if @base.respond_to?(:exception)
|
61
126
|
@base.exception("Error details", message)
|
@@ -64,22 +129,17 @@ module SmartProxyDynflowCore
|
|
64
129
|
"#{subject}\n#{message.backtrace.join("\n")}"
|
65
130
|
end
|
66
131
|
else
|
67
|
-
message
|
132
|
+
@original_formatter.call(severity, datetime, prog_name, message)
|
68
133
|
end
|
69
134
|
end
|
70
|
-
|
71
|
-
def format(message)
|
72
|
-
call(nil, nil, nil, message)
|
73
|
-
end
|
74
135
|
end
|
75
136
|
|
76
137
|
class ProxyAdapter < ::Dynflow::LoggerAdapters::Simple
|
77
138
|
def initialize(logger, level = Logger::DEBUG, _formatters = [])
|
78
139
|
@logger = logger
|
79
140
|
@logger.level = level
|
80
|
-
@
|
81
|
-
@
|
82
|
-
@dynflow_logger = apply_formatters(ProgNameWrapper.new(@logger, 'dynflow'), [ProxyStructuredFormater])
|
141
|
+
@action_logger = apply_formatters(ProgNameWrapper.new(@logger, ' action'), [])
|
142
|
+
@dynflow_logger = apply_formatters(ProgNameWrapper.new(@logger, 'dynflow'), [])
|
83
143
|
end
|
84
144
|
end
|
85
145
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SmartProxyDynflowCore
|
2
|
+
class LoggerMiddleware
|
3
|
+
def initialize(app)
|
4
|
+
@logger = SmartProxyDynflowCore::Log.instance
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
before = Time.now.to_f
|
10
|
+
status = 500
|
11
|
+
env['rack.logger'] = @logger
|
12
|
+
@logger.info { "Started #{env['REQUEST_METHOD']} #{env['PATH_INFO']} #{env['QUERY_STRING']}" }
|
13
|
+
@logger.debug { 'Headers: ' + env.select { |k, v| k.start_with? 'HTTP_' }.inspect }
|
14
|
+
if @logger.debug? && env['rack.input']
|
15
|
+
body = env['rack.input'].read
|
16
|
+
@logger.debug('Body: ' + body) unless body.empty?
|
17
|
+
env['rack.input'].rewind
|
18
|
+
end
|
19
|
+
status, = @app.call(env)
|
20
|
+
rescue Exception => e
|
21
|
+
Log.exception "Error processing request '#{::Logging.mdc['request']}", e
|
22
|
+
raise e
|
23
|
+
ensure
|
24
|
+
@logger.info do
|
25
|
+
after = Time.now.to_f
|
26
|
+
duration = (after - before) * 1000
|
27
|
+
"Finished #{env['REQUEST_METHOD']} #{env['PATH_INFO']} with #{status} (#{duration.round(2)} ms)"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SmartProxyDynflowCore
|
2
|
+
class RequestIdMiddleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
::Logging.mdc['remote_ip'] = env['REMOTE_ADDR']
|
9
|
+
if env.has_key?('HTTP_X_REQUEST_ID')
|
10
|
+
::Logging.mdc['request'] = env['HTTP_X_REQUEST_ID']
|
11
|
+
else
|
12
|
+
::Logging.mdc['request'] = SecureRandom.uuid
|
13
|
+
end
|
14
|
+
status, header, body = @app.call(env)
|
15
|
+
[status, header, ::Rack::BodyProxy.new(body) { ::Logging.mdc.clear }]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,22 +1,5 @@
|
|
1
1
|
require 'ostruct'
|
2
2
|
|
3
|
-
# Implement hash-like access for 1.9.3 and older
|
4
|
-
if RUBY_VERSION.split('.').first.to_i < 2
|
5
|
-
class OpenStruct
|
6
|
-
def [](key)
|
7
|
-
self.send key
|
8
|
-
end
|
9
|
-
|
10
|
-
def []=(key, value)
|
11
|
-
self.send "#{key}=", value
|
12
|
-
end
|
13
|
-
|
14
|
-
def to_h
|
15
|
-
marshal_dump
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
3
|
module SmartProxyDynflowCore
|
21
4
|
class Settings < OpenStruct
|
22
5
|
DEFAULT_SETTINGS = {
|
@@ -41,7 +24,12 @@ module SmartProxyDynflowCore
|
|
41
24
|
:pid_file => '/var/run/foreman-proxy/smart_proxy_dynflow_core.pid',
|
42
25
|
:daemonize => false,
|
43
26
|
:execution_plan_cleaner_age => 60 * 60 * 24,
|
44
|
-
:loaded => false
|
27
|
+
:loaded => false,
|
28
|
+
:file_logging_pattern => '%d %.8X{request} [%.1l] %m',
|
29
|
+
:system_logging_pattern => '%.8X{request} [%.1l] %m',
|
30
|
+
:file_rolling_keep => 6,
|
31
|
+
:file_rolling_size => 0,
|
32
|
+
:file_rolling_age => 'weekly'
|
45
33
|
}.freeze
|
46
34
|
|
47
35
|
PROXY_SETTINGS = %i[ssl_ca_file ssl_certificate ssl_private_key foreman_url
|
@@ -73,13 +61,7 @@ module SmartProxyDynflowCore
|
|
73
61
|
end
|
74
62
|
|
75
63
|
def self.load_from_proxy(plugin)
|
76
|
-
|
77
|
-
plugin
|
78
|
-
else
|
79
|
-
# DEPRECATION: Remove this branch when dropping support for smart-proxy < 1.16
|
80
|
-
plugin[:class]
|
81
|
-
end
|
82
|
-
settings = plugin_class.settings.to_h
|
64
|
+
settings = plugin.settings.to_h
|
83
65
|
PROXY_SETTINGS.each do |key|
|
84
66
|
SETTINGS[key] = Proxy::SETTINGS[key]
|
85
67
|
end
|
@@ -2,7 +2,6 @@ lib = File.expand_path('../lib', __FILE__)
|
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require 'smart_proxy_dynflow_core/version'
|
4
4
|
|
5
|
-
# rubocop:disable Metrics/BlockLength
|
6
5
|
Gem::Specification.new do |gem|
|
7
6
|
gem.name = "smart_proxy_dynflow_core"
|
8
7
|
gem.version = SmartProxyDynflowCore::VERSION
|
@@ -22,6 +21,8 @@ Gem::Specification.new do |gem|
|
|
22
21
|
gem.require_paths = ["lib"]
|
23
22
|
gem.license = 'GPL-3.0'
|
24
23
|
|
24
|
+
gem.required_ruby_version = '~> 2.5'
|
25
|
+
|
25
26
|
gem.add_development_dependency "bundler", ">= 1.7"
|
26
27
|
gem.add_development_dependency('minitest')
|
27
28
|
gem.add_development_dependency('mocha', '~> 1')
|
@@ -31,10 +32,11 @@ Gem::Specification.new do |gem|
|
|
31
32
|
|
32
33
|
gem.add_runtime_dependency('dynflow', "~> 1.1")
|
33
34
|
gem.add_runtime_dependency('foreman-tasks-core', '>= 0.3.3')
|
35
|
+
gem.add_runtime_dependency('logging')
|
34
36
|
gem.add_runtime_dependency('rack')
|
35
37
|
gem.add_runtime_dependency('rest-client')
|
38
|
+
gem.add_runtime_dependency('sd_notify', '~> 0.1')
|
36
39
|
gem.add_runtime_dependency('sequel')
|
37
40
|
gem.add_runtime_dependency('sinatra')
|
38
41
|
gem.add_runtime_dependency('sqlite3')
|
39
42
|
end
|
40
|
-
# rubocop:enable Metrics/BlockLength
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_dynflow_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -122,6 +122,20 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.3.3
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: logging
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
125
139
|
- !ruby/object:Gem::Dependency
|
126
140
|
name: rack
|
127
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +164,20 @@ dependencies:
|
|
150
164
|
- - ">="
|
151
165
|
- !ruby/object:Gem::Version
|
152
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: sd_notify
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0.1'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0.1'
|
153
181
|
- !ruby/object:Gem::Dependency
|
154
182
|
name: sequel
|
155
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -214,7 +242,8 @@ files:
|
|
214
242
|
- lib/smart_proxy_dynflow_core/helpers.rb
|
215
243
|
- lib/smart_proxy_dynflow_core/launcher.rb
|
216
244
|
- lib/smart_proxy_dynflow_core/log.rb
|
217
|
-
- lib/smart_proxy_dynflow_core/
|
245
|
+
- lib/smart_proxy_dynflow_core/logger_middleware.rb
|
246
|
+
- lib/smart_proxy_dynflow_core/request_id_middleware.rb
|
218
247
|
- lib/smart_proxy_dynflow_core/settings.rb
|
219
248
|
- lib/smart_proxy_dynflow_core/task_launcher_registry.rb
|
220
249
|
- lib/smart_proxy_dynflow_core/testing.rb
|
@@ -224,23 +253,23 @@ homepage: https://github.com/theforeman/smart_proxy_dynflow
|
|
224
253
|
licenses:
|
225
254
|
- GPL-3.0
|
226
255
|
metadata: {}
|
227
|
-
post_install_message:
|
256
|
+
post_install_message:
|
228
257
|
rdoc_options: []
|
229
258
|
require_paths:
|
230
259
|
- lib
|
231
260
|
required_ruby_version: !ruby/object:Gem::Requirement
|
232
261
|
requirements:
|
233
|
-
- - "
|
262
|
+
- - "~>"
|
234
263
|
- !ruby/object:Gem::Version
|
235
|
-
version: '
|
264
|
+
version: '2.5'
|
236
265
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
266
|
requirements:
|
238
267
|
- - ">="
|
239
268
|
- !ruby/object:Gem::Version
|
240
269
|
version: '0'
|
241
270
|
requirements: []
|
242
|
-
rubygems_version: 3.
|
243
|
-
signing_key:
|
271
|
+
rubygems_version: 3.1.2
|
272
|
+
signing_key:
|
244
273
|
specification_version: 4
|
245
274
|
summary: Dynflow runtime for Foreman smart proxy
|
246
275
|
test_files: []
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# Shamelessly taken from theforeman/smart-proxy @ 99e9e5b
|
2
|
-
# kudos to domcleal
|
3
|
-
|
4
|
-
require 'socket'
|
5
|
-
|
6
|
-
# Implementation of libsystemd's sd_notify API, sends current state via socket
|
7
|
-
module SmartProxyDynflowCore
|
8
|
-
class SdNotify
|
9
|
-
def active?
|
10
|
-
!ENV['NOTIFY_SOCKET'].nil?
|
11
|
-
end
|
12
|
-
|
13
|
-
def notify(message)
|
14
|
-
create_socket.tap do |socket|
|
15
|
-
socket.sendmsg(message.chomp + "\n") # ensure trailing \n
|
16
|
-
socket.close
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def ready(state = 1)
|
21
|
-
notify("READY=#{state}")
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
|
26
|
-
def create_socket
|
27
|
-
raise 'Missing NOTIFY_SOCKET environment variable, is this process running under systemd?' unless active?
|
28
|
-
Socket.new(Socket::AF_UNIX, Socket::SOCK_DGRAM, 0).tap do |socket|
|
29
|
-
socket.connect(Socket.pack_sockaddr_un(ENV['NOTIFY_SOCKET']))
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|