foreman_maintain 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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