foreman_maintain 0.0.3 → 0.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3685c87a51938c933602dc6c14326eff9dcd0f17
4
- data.tar.gz: aecc1a267b26067df5a4ecda9ffda31ddd278983
3
+ metadata.gz: 27f1643f7ff922cc3d9afb44a17f563b1fdb78e5
4
+ data.tar.gz: de21e1b4eb82ec7a0e108bd83506faa2323b541c
5
5
  SHA512:
6
- metadata.gz: e972a4b2e2375bc8af5190c66b897fb9604ebada63804fc57a73547b93169b4a919ff54439e4efb2c4438b19b0b10b35f6d4cfd7805043479c4954d2f31b4acd
7
- data.tar.gz: 521e0c73a330a750cfeee298ca9b7d2ed9341b4e863f56cb1a791df3b774a97c1fc27352d8bec14a453549fc9bb30fd3b87da059418b6266f0aca3a5e6d6269e
6
+ metadata.gz: fac7f856bb7cc2ad7b285514ce1b843dadd2beb989e9b0aa91bad8b8f3b564d906ce9e77abe98856f8d6fc5f8820ea2e350ff161c9e5cc7601c4ebeac71984d4
7
+ data.tar.gz: 90d43d34632fa926f07a0c437ad7f703ee407fb44f3ab8d4bf3d9a9ba142e42b1fe0b1e4987fbc8e5aa375f3b6f2e594334698de2332ef89620386d26276ff60
data/bin/foreman-maintain CHANGED
@@ -4,6 +4,8 @@ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
4
 
5
5
  require 'foreman_maintain'
6
6
 
7
+ CONFIG_FILE = '/etc/foreman-maintain/config/foreman_maintain.yml'.freeze
8
+
7
9
  ForemanMaintain.setup
8
10
 
9
11
  require 'foreman_maintain/cli'
@@ -0,0 +1,15 @@
1
+ # Directory where the logs are stored.
2
+ # The default file is named as /log/foreman_maintain.log
3
+ :log_dir: 'log'
4
+
5
+ # Logger levels: mention one of debug, info, warning, error, fatal
6
+ :log_level: 'error'
7
+
8
+ # Mention definitions directories. Default
9
+ # :definitions_dirs:
10
+
11
+ # Mention file path to store data
12
+ # :storage_file: 'data.yml'
13
+
14
+ # Mention directory to store whole backup data
15
+ # :backup_dir: '/lib/foreman-maintain'
@@ -0,0 +1,16 @@
1
+ # Directory where the logs are stored.
2
+ # The default file is named as /log/foreman_maintain.log
3
+ :log_dir: '/var/log/foreman-maintain/'
4
+
5
+ # Logger levels: mention one of debug, info, warning, error, fatal
6
+ # :log_level: 'error'
7
+
8
+ # Mention definitions directories. Default
9
+ # :definitions_dirs:
10
+
11
+ # Mention file path to store data
12
+ :storage_file: '/lib/foreman-maintain/data.yml'
13
+
14
+ # Mention directory to store whole backup data
15
+ :backup_dir: '/lib/foreman-maintain'
16
+
@@ -6,6 +6,8 @@ module Checks::ForemanTasks
6
6
  for_feature :foreman_tasks
7
7
  tags :pre_upgrade
8
8
  description 'Check for old tasks in paused/stopped state'
9
+ before :check_foreman_tasks_in_pending_state
10
+ after :foreman_tasks_not_paused
9
11
  end
10
12
 
11
13
  def run
@@ -6,6 +6,7 @@ module Checks::ForemanTasks
6
6
  for_feature :foreman_tasks
7
7
  tags :pre_upgrade
8
8
  description 'Check for pending tasks which are safe to delete'
9
+ before :check_foreman_tasks_in_planning_state
9
10
  end
10
11
 
11
12
  def run
@@ -6,6 +6,7 @@ module Checks::ForemanTasks
6
6
  for_feature :foreman_tasks
7
7
  tags :pre_upgrade
8
8
  description 'Check for tasks in planning state'
9
+ after :check_foreman_tasks_in_pending_state
9
10
  end
10
11
 
11
12
  def run
@@ -1,5 +1,6 @@
1
1
  module Checks::ForemanTasks
2
2
  class NotPaused < ForemanMaintain::Check
3
+ include ForemanMaintain::Concerns::Hammer
3
4
  metadata do
4
5
  for_feature :foreman_tasks
5
6
  description 'check for paused tasks'
@@ -4,6 +4,8 @@ module Checks::ForemanTasks
4
4
  for_feature :foreman_tasks
5
5
  description 'check for running tasks'
6
6
  tags :pre_upgrade
7
+ after :foreman_tasks_not_paused
8
+ before :check_old_foreman_tasks
7
9
  end
8
10
 
9
11
  def run
@@ -6,6 +6,7 @@ module Checks::SyncPlans
6
6
  for_feature :sync_plans
7
7
  description 'check for enabled sync plans'
8
8
  tags :pre_upgrade
9
+ before :disk_io
9
10
  end
10
11
 
11
12
  def run
@@ -82,11 +82,19 @@ class Features::ForemanTasks < ForemanMaintain::Feature
82
82
  end
83
83
  end
84
84
 
85
+ def resume_task_using_hammer
86
+ hammer('task resume')
87
+ end
88
+
85
89
  private
86
90
 
91
+ def parent_backup_dir
92
+ File.expand_path(ForemanMaintain.config.backup_dir)
93
+ end
94
+
87
95
  def backup_dir(state)
88
96
  @backup_dir ||=
89
- "/var/lib/foreman/backup-tasks/#{state}/#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
97
+ "#{parent_backup_dir}/backup-tasks/#{state}/#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
90
98
  end
91
99
 
92
100
  def backup_table(table, state, fkey = 'execution_plan_uuid')
@@ -1,14 +1,12 @@
1
1
  module Procedures::ForemanTasks
2
2
  class Resume < ForemanMaintain::Procedure
3
- include ForemanMaintain::Concerns::Hammer
4
-
5
3
  metadata do
6
4
  for_feature :foreman_tasks
7
5
  description 'resume paused tasks'
8
6
  end
9
7
 
10
8
  def run
11
- output << hammer('task resume')
9
+ output << feature(:foreman_tasks).resume_task_using_hammer
12
10
  end
13
11
  end
14
12
  end
@@ -5,7 +5,9 @@ module ForemanMaintain
5
5
  tags_option
6
6
 
7
7
  def execute
8
- available_checks.each { |check| print_check_info(check) }
8
+ DependencyGraph.sort(available_checks.map(&:ensure_instance)).each do |check|
9
+ print_check_info(check)
10
+ end
9
11
  end
10
12
 
11
13
  def print_check_info(check)
@@ -32,6 +32,15 @@ module ForemanMaintain
32
32
  @data[:confine_blocks] << block
33
33
  end
34
34
 
35
+ def before(*step_labels)
36
+ raise Error::MultipleBeforeDetected, step_labels if step_labels.count > 1
37
+ @data[:before].concat(step_labels)
38
+ end
39
+
40
+ def after(*step_labels)
41
+ @data[:after].concat(step_labels)
42
+ end
43
+
35
44
  # Parametrize the definition.
36
45
  #
37
46
  # == Arguments
@@ -143,11 +152,21 @@ module ForemanMaintain
143
152
  metadata[:params] || []
144
153
  end
145
154
 
155
+ def before
156
+ metadata[:before] || []
157
+ end
158
+
159
+ def after
160
+ metadata[:after] || []
161
+ end
162
+
146
163
  def initialize_metadata
147
164
  { :tags => [],
148
165
  :confine_blocks => [],
149
166
  :params => {},
150
- :preparation_steps_blocks => [] }.tap do |metadata|
167
+ :preparation_steps_blocks => [],
168
+ :before => [],
169
+ :after => [] }.tap do |metadata|
151
170
  if superclass.respond_to?(:metadata)
152
171
  metadata[:label] = superclass.metadata[:label]
153
172
  end
@@ -2,18 +2,22 @@ require 'fileutils'
2
2
  module ForemanMaintain
3
3
  class Config
4
4
  attr_accessor :pre_setup_log_messages,
5
- :config_file, :definitions_dirs, :log_level, :log_dir, :storage_file
5
+ :config_file, :definitions_dirs, :log_level, :log_dir, :storage_file,
6
+ :backup_dir
6
7
 
7
8
  def initialize(options)
8
9
  @pre_setup_log_messages = []
9
- @config_file = options.fetch(:config_file, default_config_file)
10
+ @config_file = options.fetch(:config_file, config_file_path)
10
11
  @options = load_config
11
12
  @definitions_dirs = @options.fetch(:definitions_dirs,
12
13
  [File.join(source_path, 'definitions')])
13
14
 
14
15
  @log_level = @options.fetch(:log_level, ::Logger::DEBUG)
15
- @log_dir = find_log_dir_path(@options.fetch(:log_dir, 'log'))
16
+ @log_dir = find_dir_path(@options.fetch(:log_dir, 'log'))
16
17
  @storage_file = @options.fetch(:storage_file, 'data.yml')
18
+ @backup_dir = find_dir_path(
19
+ @options.fetch(:backup_dir, '/lib/foreman-maintain')
20
+ )
17
21
  end
18
22
 
19
23
  private
@@ -30,23 +34,23 @@ module ForemanMaintain
30
34
  raise "Couldn't load configuration file. Error: #{e.message}"
31
35
  end
32
36
 
33
- def default_config_file
34
- File.join(source_path, 'config/foreman_maintain.yml')
37
+ def config_file_path
38
+ File.exist?(CONFIG_FILE) ? CONFIG_FILE : 'config/foreman_maintain.yml'
35
39
  end
36
40
 
37
41
  def source_path
38
42
  File.expand_path('../../..', __FILE__)
39
43
  end
40
44
 
41
- def find_log_dir_path(log_dir)
42
- log_dir_path = File.expand_path(log_dir)
45
+ def find_dir_path(dir_path_str)
46
+ dir_path = File.expand_path(dir_path_str)
43
47
  begin
44
- FileUtils.mkdir_p(log_dir_path, :mode => 0o750) unless File.exist?(log_dir_path)
48
+ FileUtils.mkdir_p(dir_path, :mode => 0o750) unless File.exist?(dir_path)
45
49
  rescue => e
46
- $stderr.puts "No permissions to create log dir #{log_dir}"
50
+ $stderr.puts "No permissions to create dir #{dir_path_str}"
47
51
  $stderr.puts e.message.inspect
48
52
  end
49
- log_dir_path
53
+ dir_path
50
54
  end
51
55
  end
52
56
  end
@@ -0,0 +1,89 @@
1
+ require 'tsort'
2
+
3
+ module ForemanMaintain
4
+ class DependencyGraph
5
+ include TSort
6
+
7
+ attr_reader :graph, :collection, :labels
8
+
9
+ def self.sort(collection)
10
+ new(collection).tsort.map(&:ensure_instance)
11
+ end
12
+
13
+ def initialize(collection)
14
+ @graph = Hash.new([])
15
+ @collection = collection
16
+ @labels = extract_labels
17
+ generate_label_graph
18
+ convert_label_graph_to_object_graph
19
+ end
20
+
21
+ def add_to_graph(key, dependencies = [])
22
+ return unless key
23
+
24
+ dependencies = dependencies.map do |dep|
25
+ next unless labels.include?(dep)
26
+ dep
27
+ end.compact
28
+
29
+ graph[key] = dependencies
30
+ end
31
+
32
+ def tsort_each_node(&block)
33
+ graph.each_key(&block)
34
+ end
35
+
36
+ def tsort_each_child(node, &block)
37
+ graph.fetch(node).each(&block)
38
+ end
39
+
40
+ private
41
+
42
+ def cache
43
+ ForemanMaintain.cache
44
+ end
45
+
46
+ def convert_label_graph_to_object_graph
47
+ graph.keys.each do |key|
48
+ graph[cache.fetch(key)] = graph[key].map { |dep| cache.fetch(dep) }
49
+ graph.delete(key)
50
+ end
51
+
52
+ graph
53
+ end
54
+
55
+ def extract_labels
56
+ collection.map(&:label)
57
+ end
58
+
59
+ def find_class(dep)
60
+ case dep
61
+ when Class
62
+ dep
63
+ when String
64
+ if dep.include?('::')
65
+ dep.split('::').reduce(Object) { |o, e| o.const_get(e) }
66
+ else
67
+ cache.fetch(dep)
68
+ end
69
+ else
70
+ cache.fetch(dep)
71
+ end
72
+ end
73
+
74
+ def generate_label_graph
75
+ collection.each do |object|
76
+ klass = object.class
77
+ key = object.label
78
+
79
+ add_to_graph(klass.before.first, [key])
80
+ add_to_graph(key, klass.after)
81
+ map_label_to_object(object)
82
+ end
83
+ end
84
+
85
+ def map_label_to_object(object)
86
+ cache.fetch(object.label, object)
87
+ end
88
+ end
89
+ end
@@ -6,6 +6,16 @@ module ForemanMaintain
6
6
  class Warn < StandardError
7
7
  end
8
8
 
9
+ class MultipleBeforeDetected < StandardError
10
+ def initialize(step_labels)
11
+ @step_labels = step_labels
12
+ end
13
+
14
+ def message
15
+ "multiple metadata detected instead of 1. \n before [#{@step_labels.join(', ')}]\n"
16
+ end
17
+ end
18
+
9
19
  class ExecutionError < StandardError
10
20
  attr_reader :command, :input, :output, :exit_status
11
21
 
@@ -0,0 +1,34 @@
1
+ require 'singleton'
2
+
3
+ module ForemanMaintain
4
+ class ObjectCache
5
+ include Singleton
6
+
7
+ attr_reader :cache
8
+
9
+ def initialize
10
+ @cache = {}
11
+ end
12
+
13
+ def fetch(key, object = nil)
14
+ hit(key) || miss(key, object)
15
+ end
16
+
17
+ private
18
+
19
+ def add(key, object)
20
+ return if key.nil? || object.nil?
21
+ cache[key.to_sym] = object
22
+ end
23
+
24
+ def hit(key)
25
+ cache.fetch(key, nil)
26
+ end
27
+
28
+ def miss(key, object)
29
+ object ||= ForemanMaintain.detector.available_checks(:label => key).first
30
+ add(key, object)
31
+ hit(key)
32
+ end
33
+ end
34
+ end
@@ -29,6 +29,7 @@ module ForemanMaintain
29
29
 
30
30
  def run_scenario(scenario)
31
31
  @steps_to_run = scenario.steps.dup
32
+ @steps_to_run = ForemanMaintain::DependencyGraph.sort(@steps_to_run)
32
33
  @reporter.before_scenario_starts(scenario)
33
34
  while !@quit && !@steps_to_run.empty?
34
35
  step = @steps_to_run.shift
@@ -16,6 +16,7 @@ module ForemanMaintain
16
16
  @filter_tags = filter[:tags]
17
17
  @filter_label = filter[:label]
18
18
  @steps = ForemanMaintain.available_checks(filter).map(&:ensure_instance)
19
+ @steps = DependencyGraph.sort(@steps)
19
20
  end
20
21
 
21
22
  def description
@@ -1,3 +1,3 @@
1
1
  module ForemanMaintain
2
- VERSION = '0.0.3'.freeze
2
+ VERSION = '0.0.4'.freeze
3
3
  end
@@ -18,10 +18,12 @@ module ForemanMaintain
18
18
  require 'foreman_maintain/yaml_storage'
19
19
  require 'foreman_maintain/config'
20
20
  require 'foreman_maintain/detector'
21
+ require 'foreman_maintain/dependency_graph'
21
22
  require 'foreman_maintain/param'
22
23
  require 'foreman_maintain/feature'
23
24
  require 'foreman_maintain/executable'
24
25
  require 'foreman_maintain/check'
26
+ require 'foreman_maintain/object_cache'
25
27
  require 'foreman_maintain/procedure'
26
28
  require 'foreman_maintain/scenario'
27
29
  require 'foreman_maintain/runner'
@@ -62,6 +64,10 @@ module ForemanMaintain
62
64
  end
63
65
  end
64
66
 
67
+ def cache
68
+ ObjectCache.instance
69
+ end
70
+
65
71
  def detector
66
72
  @detector ||= Detector.new
67
73
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_maintain
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-16 00:00:00.000000000 Z
11
+ date: 2017-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clamp
@@ -107,6 +107,8 @@ files:
107
107
  - LICENSE
108
108
  - README.md
109
109
  - bin/foreman-maintain
110
+ - config/foreman_maintain.yml.example
111
+ - config/foreman_maintain.yml.packaging
110
112
  - definitions/checks/disk_speed_minimal.rb
111
113
  - definitions/checks/foreman_tasks/invalid/check_old.rb
112
114
  - definitions/checks/foreman_tasks/invalid/check_pending_state.rb
@@ -150,10 +152,12 @@ files:
150
152
  - lib/foreman_maintain/concerns/system_helpers.rb
151
153
  - lib/foreman_maintain/config.rb
152
154
  - lib/foreman_maintain/core_ext.rb
155
+ - lib/foreman_maintain/dependency_graph.rb
153
156
  - lib/foreman_maintain/detector.rb
154
157
  - lib/foreman_maintain/error.rb
155
158
  - lib/foreman_maintain/executable.rb
156
159
  - lib/foreman_maintain/feature.rb
160
+ - lib/foreman_maintain/object_cache.rb
157
161
  - lib/foreman_maintain/param.rb
158
162
  - lib/foreman_maintain/procedure.rb
159
163
  - lib/foreman_maintain/reporter.rb