foreman-tasks 0.10.0 → 0.10.1
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/.rubocop_todo.yml +0 -2
- data/app/assets/javascripts/{trigger_form.js → foreman_tasks/trigger_form.js} +0 -0
- data/app/controllers/foreman_tasks/recurring_logics_controller.rb +6 -1
- data/app/controllers/foreman_tasks/tasks_controller.rb +16 -2
- data/app/lib/actions/proxy_action.rb +7 -0
- data/app/models/foreman_tasks/task/dynflow_task.rb +19 -4
- data/app/models/foreman_tasks/task/summarizer.rb +3 -1
- data/app/views/common/_trigger_form.html.erb +1 -1
- data/app/views/foreman_tasks/recurring_logics/index.html.erb +1 -2
- data/app/views/foreman_tasks/tasks/dashboard/_latest_tasks_in_error_warning.html.erb +1 -1
- data/app/views/foreman_tasks/tasks/dashboard/_tasks_status.html.erb +2 -0
- data/app/views/foreman_tasks/tasks/index.html.erb +1 -2
- data/config/routes.rb +1 -0
- data/foreman-tasks.gemspec +1 -3
- data/lib/foreman_tasks.rb +2 -1
- data/lib/foreman_tasks/dynflow.rb +2 -108
- data/lib/foreman_tasks/dynflow/configuration.rb +7 -142
- data/lib/foreman_tasks/dynflow/persistence.rb +3 -2
- data/lib/foreman_tasks/engine.rb +2 -2
- data/lib/foreman_tasks/version.rb +1 -1
- data/test/controllers/recurring_logics_controller_test.rb +14 -0
- data/test/controllers/tasks_controller_test.rb +17 -0
- data/test/unit/otp_manager_test.rb +70 -0
- metadata +12 -43
- data/bin/dynflow-executor +0 -71
- data/bin/foreman-tasks +0 -5
- data/deploy/foreman-tasks.init +0 -231
- data/deploy/foreman-tasks.service +0 -16
- data/deploy/foreman-tasks.sysconfig +0 -26
- data/lib/foreman_tasks/dynflow/daemon.rb +0 -143
- data/lib/foreman_tasks/tasks/dynflow.rake +0 -7
- data/test/unit/daemon_test.rb +0 -86
@@ -1,16 +0,0 @@
|
|
1
|
-
[Unit]
|
2
|
-
Description=Foreman jobs daemon
|
3
|
-
Documentation=https://github.com/theforeman/foreman-tasks
|
4
|
-
After=network.target remote-fs.target nss-lookup.target
|
5
|
-
|
6
|
-
[Service]
|
7
|
-
Type=forking
|
8
|
-
User=foreman
|
9
|
-
TimeoutSec=600
|
10
|
-
WorkingDirectory=/usr/share/foreman
|
11
|
-
ExecStart=/usr/bin/foreman-tasks start
|
12
|
-
ExecStop=/usr/bin/foreman-tasks stop
|
13
|
-
EnvironmentFile=-/etc/sysconfig/foreman-tasks
|
14
|
-
|
15
|
-
[Install]
|
16
|
-
WantedBy=multi-user.target
|
@@ -1,26 +0,0 @@
|
|
1
|
-
FOREMAN_USER=foreman
|
2
|
-
BUNDLER_EXT_HOME=/usr/share/foreman
|
3
|
-
RAILS_RELATIVE_URL_ROOT=$FOREMAN_PREFIX
|
4
|
-
RAILS_ENV=production
|
5
|
-
FOREMAN_LOGGING=warn
|
6
|
-
FOREMAN_LOGGING_SQL=warn
|
7
|
-
FOREMAN_TASK_PARAMS="-p foreman"
|
8
|
-
FOREMAN_LOG_DIR=/var/log/foreman
|
9
|
-
|
10
|
-
RUBY_GC_MALLOC_LIMIT=4000100
|
11
|
-
RUBY_GC_MALLOC_LIMIT_MAX=16000100
|
12
|
-
RUBY_GC_MALLOC_LIMIT_GROWTH_FACTOR=1.1
|
13
|
-
RUBY_GC_OLDMALLOC_LIMIT=16000100
|
14
|
-
RUBY_GC_OLDMALLOC_LIMIT_MAX=16000100
|
15
|
-
|
16
|
-
#Set the number of executors you want to run
|
17
|
-
#EXECUTORS_COUNT=1
|
18
|
-
|
19
|
-
#Set memory limit for executor process, before it's restarted automatically
|
20
|
-
#EXECUTOR_MEMORY_LIMIT=2gb
|
21
|
-
|
22
|
-
#Set delay before first memory polling to let executor initialize (in sec)
|
23
|
-
#EXECUTOR_MEMORY_MONITOR_DELAY=7200 #default: 2 hours
|
24
|
-
|
25
|
-
#Set memory polling interval, process memory will be checked every N seconds.
|
26
|
-
#EXECUTOR_MEMORY_MONITOR_INTERVAL=60
|
@@ -1,143 +0,0 @@
|
|
1
|
-
require 'fileutils'
|
2
|
-
require 'daemons'
|
3
|
-
require 'get_process_mem'
|
4
|
-
require 'dynflow/watchers/memory_consumption_watcher'
|
5
|
-
|
6
|
-
module ForemanTasks
|
7
|
-
class Dynflow::Daemon
|
8
|
-
attr_reader :dynflow_memory_watcher_class,
|
9
|
-
:daemons_class
|
10
|
-
|
11
|
-
# make Daemon dependency injection ready for testing purposes
|
12
|
-
def initialize(
|
13
|
-
dynflow_memory_watcher_class = ::Dynflow::Watchers::MemoryConsumptionWatcher,
|
14
|
-
daemons_class = ::Daemons
|
15
|
-
)
|
16
|
-
@dynflow_memory_watcher_class = dynflow_memory_watcher_class
|
17
|
-
@daemons_class = daemons_class
|
18
|
-
end
|
19
|
-
|
20
|
-
# load the Rails environment and initialize the executor
|
21
|
-
# in this thread.
|
22
|
-
def run(foreman_root = Dir.pwd, options = {})
|
23
|
-
STDERR.puts('Starting Rails environment')
|
24
|
-
foreman_env_file = File.expand_path('./config/environment.rb', foreman_root)
|
25
|
-
unless File.exist?(foreman_env_file)
|
26
|
-
raise "#{foreman_root} doesn't seem to be a foreman root directory"
|
27
|
-
end
|
28
|
-
|
29
|
-
STDERR.puts("Starting dynflow with the following options: #{options}")
|
30
|
-
|
31
|
-
ForemanTasks.dynflow.executor!
|
32
|
-
|
33
|
-
if options[:memory_limit] > 0
|
34
|
-
ForemanTasks.dynflow.config.on_init do |world|
|
35
|
-
memory_watcher = initialize_memory_watcher(world, options[:memory_limit], options)
|
36
|
-
world.terminated.on_completion do
|
37
|
-
STDERR.puts("World has been terminated")
|
38
|
-
memory_watcher = nil # the object can be disposed
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
require foreman_env_file
|
44
|
-
STDERR.puts("Everything ready for world: #{(ForemanTasks.dynflow.initialized? ? ForemanTasks.dynflow.world.id : nil)}")
|
45
|
-
sleep
|
46
|
-
ensure
|
47
|
-
STDERR.puts('Exiting')
|
48
|
-
end
|
49
|
-
|
50
|
-
# run the executor as a daemon
|
51
|
-
def run_background(command = 'start', options = {})
|
52
|
-
options = default_options.merge(options)
|
53
|
-
FileUtils.mkdir_p(options[:pid_dir])
|
54
|
-
begin
|
55
|
-
require 'daemons'
|
56
|
-
rescue LoadError
|
57
|
-
raise "You need to add gem 'daemons' to your Gemfile if you wish to use it."
|
58
|
-
end
|
59
|
-
|
60
|
-
unless %w[start stop restart run].include?(command)
|
61
|
-
raise "Command exptected to be 'start', 'stop', 'restart', 'run', was #{command.inspect}"
|
62
|
-
end
|
63
|
-
|
64
|
-
STDERR.puts("Dynflow Executor: #{command} in progress")
|
65
|
-
|
66
|
-
options[:executors_count].times do
|
67
|
-
daemons_class.run_proc(
|
68
|
-
options[:process_name],
|
69
|
-
daemons_options(command, options)
|
70
|
-
) do |*_args|
|
71
|
-
begin
|
72
|
-
::Logging.reopen
|
73
|
-
run(options[:foreman_root], options)
|
74
|
-
rescue => e
|
75
|
-
STDERR.puts e.message
|
76
|
-
Foreman::Logging.exception('Failed running foreman-tasks daemon', e)
|
77
|
-
exit 1
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
protected
|
84
|
-
|
85
|
-
def world
|
86
|
-
ForemanTasks.dynflow.world
|
87
|
-
end
|
88
|
-
|
89
|
-
private
|
90
|
-
|
91
|
-
def daemons_options(command, options)
|
92
|
-
{
|
93
|
-
:multiple => true,
|
94
|
-
:dir => options[:pid_dir],
|
95
|
-
:log_dir => options[:log_dir],
|
96
|
-
:dir_mode => :normal,
|
97
|
-
:monitor => true,
|
98
|
-
:log_output => true,
|
99
|
-
:log_output_syslog => true,
|
100
|
-
:monitor_interval => [options[:memory_polling_interval] / 2, 30].min,
|
101
|
-
:ARGV => [command]
|
102
|
-
}
|
103
|
-
end
|
104
|
-
|
105
|
-
def default_options
|
106
|
-
{
|
107
|
-
foreman_root: Dir.pwd,
|
108
|
-
process_name: 'dynflow_executor',
|
109
|
-
pid_dir: "#{Rails.root}/tmp/pids",
|
110
|
-
log_dir: File.join(Rails.root, 'log'),
|
111
|
-
wait_attempts: 300,
|
112
|
-
wait_sleep: 1,
|
113
|
-
executors_count: (ENV['EXECUTORS_COUNT'] || 1).to_i,
|
114
|
-
memory_limit: begin
|
115
|
-
(ENV['EXECUTOR_MEMORY_LIMIT'] || '').to_gb.gigabytes
|
116
|
-
rescue RuntimeError
|
117
|
-
ENV['EXECUTOR_MEMORY_LIMIT'].to_i
|
118
|
-
end,
|
119
|
-
memory_init_delay: (ENV['EXECUTOR_MEMORY_MONITOR_DELAY'] || 7200).to_i, # 2 hours
|
120
|
-
memory_polling_interval: (ENV['EXECUTOR_MEMORY_MONITOR_INTERVAL'] || 60).to_i
|
121
|
-
}
|
122
|
-
end
|
123
|
-
|
124
|
-
def initialize_memory_watcher(world, memory_limit, options)
|
125
|
-
watcher_options = {}
|
126
|
-
watcher_options[:polling_interval] = options[:memory_polling_interval]
|
127
|
-
watcher_options[:initial_wait] = options[:memory_init_delay]
|
128
|
-
watcher_options[:memory_checked_callback] = ->(current_memory, memory_limit) { log_memory_within_limit(current_memory, memory_limit) }
|
129
|
-
watcher_options[:memory_limit_exceeded_callback] = ->(current_memory, memory_limit) { log_memory_limit_exceeded(current_memory, memory_limit) }
|
130
|
-
dynflow_memory_watcher_class.new(world, memory_limit, watcher_options)
|
131
|
-
end
|
132
|
-
|
133
|
-
def log_memory_limit_exceeded(current_memory, memory_limit)
|
134
|
-
message = "Memory level exceeded, registered #{current_memory} bytes, which is greater than #{memory_limit} limit."
|
135
|
-
Foreman::Logging.logger('foreman-tasks').error(message)
|
136
|
-
end
|
137
|
-
|
138
|
-
def log_memory_within_limit(current_memory, memory_limit)
|
139
|
-
message = "Memory level OK, registered #{current_memory} bytes, which is less than #{memory_limit} limit."
|
140
|
-
Foreman::Logging.logger('foreman-tasks').debug(message)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
data/test/unit/daemon_test.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
class DaemonTest < ActiveSupport::TestCase
|
4
|
-
setup do
|
5
|
-
@dynflow_memory_watcher = mock('memory_watcher')
|
6
|
-
@daemons = mock('daemons')
|
7
|
-
@daemon = ForemanTasks::Dynflow::Daemon.new(
|
8
|
-
@dynflow_memory_watcher,
|
9
|
-
@daemons
|
10
|
-
)
|
11
|
-
@world_class = mock('dummy world factory')
|
12
|
-
@dummy_world = Dynflow::Testing::DummyWorld.new
|
13
|
-
@dummy_world.stubs(:auto_execute)
|
14
|
-
@dummy_world.stubs(:terminated).returns(Concurrent.event)
|
15
|
-
@world_class.stubs(:new).returns(@dummy_world)
|
16
|
-
@dynflow = ForemanTasks::Dynflow.new(@world_class)
|
17
|
-
ForemanTasks.stubs(:dynflow).returns(@dynflow)
|
18
|
-
@dynflow.require!
|
19
|
-
end
|
20
|
-
|
21
|
-
test 'run command creates a watcher if memory_limit option specified' do
|
22
|
-
current_folder = File.expand_path('../', __FILE__)
|
23
|
-
|
24
|
-
@dynflow_memory_watcher.expects(:new).with do |_world, memory_limit, _watcher_options|
|
25
|
-
memory_limit == 1000
|
26
|
-
end
|
27
|
-
@daemon.stubs(:sleep).returns(true) # don't pause the execution
|
28
|
-
|
29
|
-
@daemon.run(current_folder, memory_limit: 1000)
|
30
|
-
# initialization should be performed inside the foreman environment,
|
31
|
-
# which is mocked here
|
32
|
-
@dynflow.initialize!
|
33
|
-
end
|
34
|
-
|
35
|
-
test 'run command sets parameters to watcher' do
|
36
|
-
current_folder = File.expand_path('../', __FILE__)
|
37
|
-
|
38
|
-
@dynflow_memory_watcher.expects(:new).with do |_world, memory_limit, watcher_options|
|
39
|
-
memory_limit == 1000 &&
|
40
|
-
watcher_options[:polling_interval] == 100 &&
|
41
|
-
watcher_options[:initial_wait] == 200
|
42
|
-
end
|
43
|
-
@daemon.stubs(:sleep).returns(true) # don't pause the execution
|
44
|
-
|
45
|
-
@daemon.run(
|
46
|
-
current_folder,
|
47
|
-
memory_limit: 1000,
|
48
|
-
memory_polling_interval: 100,
|
49
|
-
memory_init_delay: 200
|
50
|
-
)
|
51
|
-
# initialization should be performed inside the foreman environment,
|
52
|
-
# which is mocked here
|
53
|
-
@dynflow.initialize!
|
54
|
-
end
|
55
|
-
|
56
|
-
test 'run_background command executes run with all params set as a daemon' do
|
57
|
-
@daemon.expects(:run).twice.with do |_folder, options|
|
58
|
-
options[:memory_limit] == 1000 &&
|
59
|
-
options[:memory_init_delay] == 100 &&
|
60
|
-
options[:memory_polling_interval] == 200
|
61
|
-
end
|
62
|
-
@daemons.expects(:run_proc).twice.yields
|
63
|
-
|
64
|
-
@daemon.run_background(
|
65
|
-
'start',
|
66
|
-
executors_count: 2,
|
67
|
-
memory_limit: 1000,
|
68
|
-
memory_init_delay: 100,
|
69
|
-
memory_polling_interval: 200
|
70
|
-
)
|
71
|
-
end
|
72
|
-
|
73
|
-
test 'default options read values from ENV' do
|
74
|
-
ENV['EXECUTORS_COUNT'] = '2'
|
75
|
-
ENV['EXECUTOR_MEMORY_LIMIT'] = '1gb'
|
76
|
-
ENV['EXECUTOR_MEMORY_MONITOR_DELAY'] = '3'
|
77
|
-
ENV['EXECUTOR_MEMORY_MONITOR_INTERVAL'] = '4'
|
78
|
-
|
79
|
-
actual = @daemon.send(:default_options)
|
80
|
-
|
81
|
-
assert_equal 2, actual[:executors_count]
|
82
|
-
assert_equal 1.gigabytes, actual[:memory_limit]
|
83
|
-
assert_equal 3, actual[:memory_init_delay]
|
84
|
-
assert_equal 4, actual[:memory_polling_interval]
|
85
|
-
end
|
86
|
-
end
|