foreman_dlm 0.1.0 → 2.0.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/README.md +18 -6
- data/app/controllers/api/v2/dlmlock_events_controller.rb +42 -0
- data/app/controllers/api/v2/dlmlocks_controller.rb +31 -16
- data/app/controllers/concerns/foreman_dlm/find_host_by_client_cert.rb +7 -13
- data/app/controllers/concerns/foreman_dlm/find_host_by_ip.rb +1 -1
- data/app/controllers/concerns/foreman_dlm/update_checkin_time.rb +22 -0
- data/app/controllers/foreman_dlm/application_controller.rb +19 -0
- data/app/controllers/foreman_dlm/dlmlocks_controller.rb +82 -0
- data/app/helpers/foreman_dlm/dlmlock_helper.rb +33 -0
- data/app/jobs/foreman_dlm/refresh_dlmlock_status.rb +17 -0
- data/app/models/concerns/foreman_dlm/dlm_facet_host_extensions.rb +13 -0
- data/app/models/concerns/foreman_dlm/expirable.rb +36 -0
- data/app/models/concerns/foreman_dlm/host_extensions.rb +21 -2
- data/app/models/concerns/foreman_dlm/host_monitoring_extensions.rb +2 -0
- data/app/models/concerns/foreman_dlm/user_extensions.rb +13 -0
- data/app/models/foreman_dlm/dlm_facet.rb +7 -0
- data/app/models/foreman_dlm/dlmlock/update.rb +9 -0
- data/app/models/foreman_dlm/dlmlock.rb +137 -0
- data/app/models/foreman_dlm/dlmlock_event.rb +23 -0
- data/app/models/host_status/dlmlock_status.rb +44 -0
- data/app/views/api/v2/dlmlock_events/index.json.rabl +2 -0
- data/app/views/api/v2/dlmlocks/show.json.rabl +1 -1
- data/app/views/api/v2/errors/precondition_failed.json.rabl +1 -1
- data/app/views/foreman_dlm/api/v2/dlm_facets/base.json.rabl +1 -0
- data/app/views/foreman_dlm/api/v2/dlm_facets/base_with_root.json.rabl +3 -0
- data/app/views/foreman_dlm/api/v2/dlm_facets/show.json.rabl +3 -0
- data/app/views/foreman_dlm/dlmlocks/_details.html.erb +42 -0
- data/app/views/{dlmlocks → foreman_dlm/dlmlocks}/_list.html.erb +3 -1
- data/app/views/foreman_dlm/dlmlocks/index.html.erb +2 -0
- data/app/views/foreman_dlm/dlmlocks/show.html.erb +10 -0
- data/app/views/{dlmlocks → foreman_dlm/dlmlocks}/welcome.html.erb +2 -2
- data/app/views/hosts/_dlmlocks_tab.html.erb +39 -0
- data/config/routes.rb +20 -13
- data/contrib/systemd/foreman-dlm-expire-events.service +10 -0
- data/contrib/systemd/foreman-dlm-expire-events.timer +8 -0
- data/db/migrate/20170824084100_add_dlmlock.foreman_dlm.rb +1 -1
- data/db/migrate/20180627150003_rename_dlmlock_sti_models.rb +9 -0
- data/db/migrate/20180704162345_add_dlmlock_events.rb +11 -0
- data/db/migrate/20180711090022_add_hosts_fk_to_dlmlocks.rb +5 -0
- data/db/migrate/20180711111903_create_dlm_facets.foreman_dlm.rb +10 -0
- data/db/migrate/20180713113208_update_permissions_for_scoped_models.rb +13 -0
- data/lib/foreman_dlm/engine.rb +58 -19
- data/lib/foreman_dlm/version.rb +1 -1
- data/lib/tasks/dlmlock_events.rake +19 -0
- data/lib/tasks/foreman_dlm_tasks.rake +2 -4
- data/test/controllers/api/v2/dlmlocks_controller_test.rb +73 -52
- data/test/controllers/api/v2/dlmlocks_dlmlock_events_controller_test.rb +81 -0
- data/test/controllers/api/v2/hosts_controller_test.rb +28 -0
- data/test/controllers/find_host_by_client_cert_test.rb +2 -2
- data/test/controllers/foreman_dlm/dlmlocks_test.rb +55 -0
- data/test/controllers/hosts_controller_test.rb +12 -0
- data/test/factories/dlm_facets.rb +6 -0
- data/test/factories/dlmlock.rb +6 -2
- data/test/factories/dlmlock_events.rb +13 -0
- data/test/factories/host.rb +7 -0
- data/test/integration/foreman_dlm/dlmlocks_test.rb +28 -0
- data/test/jobs/refresh_dlmlock_status_test.rb +10 -0
- data/test/models/foreman_dlm/dlm_facet_test.rb +13 -0
- data/test/models/foreman_dlm/dlmlock_event_test.rb +19 -0
- data/test/models/foreman_dlm/dlmlock_test.rb +307 -0
- data/test/models/host_managed_test.rb +41 -0
- data/test/models/host_monitoring_test.rb +1 -1
- data/test/models/host_status/dlmlock_status_test.rb +45 -0
- data/test/models/user_test.rb +5 -0
- data/test/test_plugin_helper.rb +5 -3
- metadata +108 -30
- data/app/controllers/dlmlocks_controller.rb +0 -13
- data/app/models/dlmlock/update.rb +0 -5
- data/app/models/dlmlock.rb +0 -79
- data/app/views/dlmlocks/_details.html.erb +0 -35
- data/app/views/dlmlocks/index.html.erb +0 -2
- data/app/views/dlmlocks/show.html.erb +0 -7
- data/test/controllers/dlmlocks_test.rb +0 -24
- data/test/models/dlmlock_test.rb +0 -201
@@ -0,0 +1,137 @@
|
|
1
|
+
module ForemanDlm
|
2
|
+
class Dlmlock < ApplicationRecord
|
3
|
+
include Authorizable
|
4
|
+
|
5
|
+
def self.humanize_class_name
|
6
|
+
N_('Distributed Lock')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.dlm_stale_time
|
10
|
+
(Setting[:dlm_stale_time] || 4).hours
|
11
|
+
end
|
12
|
+
|
13
|
+
belongs_to_host
|
14
|
+
|
15
|
+
has_many :dlmlock_events,
|
16
|
+
class_name: '::ForemanDlm::DlmlockEvent',
|
17
|
+
dependent: :destroy,
|
18
|
+
inverse_of: :dlmlock
|
19
|
+
|
20
|
+
validates :name, presence: true, uniqueness: true
|
21
|
+
|
22
|
+
after_save :log_enable_or_disable_event, if: -> { saved_change_to_enabled? }
|
23
|
+
after_save :log_release_and_acquire_events, if: -> { saved_change_to_host_id? }
|
24
|
+
|
25
|
+
def log_enable_or_disable_event
|
26
|
+
event_type = enabled ? :enable : :disable
|
27
|
+
log_event(host, event_type)
|
28
|
+
end
|
29
|
+
|
30
|
+
def log_release_and_acquire_events
|
31
|
+
old_host_id = saved_changes[:host_id].first
|
32
|
+
old_host = Host.find_by(id: old_host_id) if old_host_id
|
33
|
+
log_event(old_host, :release) if old_host
|
34
|
+
log_event(host, :acquire) if host
|
35
|
+
end
|
36
|
+
|
37
|
+
scope :locked, -> { where.not(host_id: nil) }
|
38
|
+
scope :stale, -> { locked.where('updated_at < ?', Time.now.utc - dlm_stale_time) }
|
39
|
+
|
40
|
+
scoped_search :on => :name, :complete_value => true, :default_order => true
|
41
|
+
scoped_search :relation => :host, :on => :name, :complete_value => true, :rename => :host
|
42
|
+
scoped_search :on => :type, :complete_value => true, :default_order => true
|
43
|
+
scoped_search :on => :enabled, :complete_value => { :true => true, :false => false }, :only_explicit => true
|
44
|
+
|
45
|
+
attr_accessor :old
|
46
|
+
|
47
|
+
def acquire!(host)
|
48
|
+
return false unless host.can_acquire_update_locks?
|
49
|
+
|
50
|
+
result = atomic_update(nil, host)
|
51
|
+
ForemanDlm::RefreshDlmlockStatus.set(wait: self.class.dlm_stale_time).perform_later([host.id]) if result
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
55
|
+
def release!(host)
|
56
|
+
atomic_update(host, nil)
|
57
|
+
end
|
58
|
+
|
59
|
+
def enable!
|
60
|
+
update(enabled: true)
|
61
|
+
end
|
62
|
+
|
63
|
+
def disable!
|
64
|
+
update(enabled: false)
|
65
|
+
end
|
66
|
+
|
67
|
+
def locked_by?(host)
|
68
|
+
self.host == host
|
69
|
+
end
|
70
|
+
alias acquired_by? locked_by?
|
71
|
+
|
72
|
+
def disabled?
|
73
|
+
!enabled?
|
74
|
+
end
|
75
|
+
|
76
|
+
def locked?
|
77
|
+
host.present?
|
78
|
+
end
|
79
|
+
alias taken? locked?
|
80
|
+
|
81
|
+
def humanized_type
|
82
|
+
_('Generic Lock')
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def atomic_update(old_host, new_host)
|
88
|
+
changes = { host_id: new_host.try(:id) }
|
89
|
+
self.old = dup
|
90
|
+
|
91
|
+
query = {
|
92
|
+
id: id,
|
93
|
+
host_id: [new_host.try(:id), old_host.try(:id)],
|
94
|
+
enabled: true
|
95
|
+
}
|
96
|
+
|
97
|
+
updated = self.class.where(query).update(changes.merge(updated_at: Time.now.utc))
|
98
|
+
|
99
|
+
unless updated.count.zero?
|
100
|
+
reload
|
101
|
+
process_host_change(old_host, new_host)
|
102
|
+
[old_host, new_host].compact.each(&:refresh_dlmlock_status)
|
103
|
+
return true
|
104
|
+
end
|
105
|
+
|
106
|
+
log_event(host, :fail)
|
107
|
+
|
108
|
+
false
|
109
|
+
end
|
110
|
+
|
111
|
+
def process_host_change(old_host, new_host)
|
112
|
+
return if host.try(:id) == old.host.try(:id)
|
113
|
+
|
114
|
+
run_callback(old_host, :unlock) if old.host
|
115
|
+
|
116
|
+
return unless host
|
117
|
+
|
118
|
+
run_callback(new_host, :lock)
|
119
|
+
end
|
120
|
+
|
121
|
+
def log_event(host, event_type)
|
122
|
+
DlmlockEvent.create!(
|
123
|
+
dlmlock: self,
|
124
|
+
event_type: event_type,
|
125
|
+
host: host,
|
126
|
+
user: User.current
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def run_callback(h, callback)
|
131
|
+
h.run_callbacks callback do
|
132
|
+
logger.debug { "custom hook after_#{callback} on #{h} will be executed if defined." }
|
133
|
+
true
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ForemanDlm
|
2
|
+
class DlmlockEvent < ApplicationRecord
|
3
|
+
include Authorizable
|
4
|
+
include Expirable
|
5
|
+
|
6
|
+
TYPES = %w[release acquire enable disable fail].freeze
|
7
|
+
validates :event_type, inclusion: { in: TYPES }
|
8
|
+
|
9
|
+
def self.humanize_class_name
|
10
|
+
N_('Distributed Lock Event')
|
11
|
+
end
|
12
|
+
|
13
|
+
belongs_to_host
|
14
|
+
belongs_to :dlmlock, inverse_of: :dlmlock_events, class_name: 'ForemanDlm::Dlmlock'
|
15
|
+
belongs_to :user, inverse_of: :dlmlock_events
|
16
|
+
|
17
|
+
scoped_search on: :event_type, complete_value: true
|
18
|
+
|
19
|
+
def humanized_type
|
20
|
+
_('Dlmlock Event')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module HostStatus
|
2
|
+
class DlmlockStatus < Status
|
3
|
+
OK = 0
|
4
|
+
STALE = 1
|
5
|
+
|
6
|
+
def self.status_name
|
7
|
+
N_('Distributed Lock')
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_label(_options = {})
|
11
|
+
case to_status
|
12
|
+
when OK
|
13
|
+
N_('Ok')
|
14
|
+
when STALE
|
15
|
+
N_('Stale')
|
16
|
+
else
|
17
|
+
N_('Unknown')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_global(_options = {})
|
22
|
+
case to_status
|
23
|
+
when OK
|
24
|
+
HostStatus::Global::OK
|
25
|
+
else
|
26
|
+
HostStatus::Global::ERROR
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_status(_options = {})
|
31
|
+
ok? ? OK : STALE
|
32
|
+
end
|
33
|
+
|
34
|
+
def relevant?(_options = {})
|
35
|
+
host.dlmlocks.any?
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def ok?
|
41
|
+
host.dlmlocks.stale.empty?
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
attributes :id, :last_checkin_at
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<% if authorizer.can?(:view_dlmlock_events) %>
|
2
|
+
<table class="<%= table_css_classes('table-fixed') %>">
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th><%= _("Host") %></th>
|
6
|
+
<th><%= _("User") %></th>
|
7
|
+
<th><%= _("Type") %></th>
|
8
|
+
<th><%= _("Timestamp") %></th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% @dlmlock.dlmlock_events.includes(:user).reorder(created_at: :desc).each do |event| %>
|
13
|
+
|
14
|
+
<tr>
|
15
|
+
<td>
|
16
|
+
<% if event.host %>
|
17
|
+
<%= link_to_if_authorized(event.host.name, hash_for_host_path(:id => event.host)) %>
|
18
|
+
<% end %>
|
19
|
+
</td>
|
20
|
+
|
21
|
+
<td>
|
22
|
+
<% if event.user %>
|
23
|
+
<% if event.user.hidden? %>
|
24
|
+
<em><%= event.user.name %></em>
|
25
|
+
<% else %>
|
26
|
+
<%= link_to_if_authorized(event.user.name, hash_for_edit_user_path(event.user)) %>
|
27
|
+
<% end %>
|
28
|
+
<% end %>
|
29
|
+
</td>
|
30
|
+
|
31
|
+
<td>
|
32
|
+
<%= _(event.event_type.humanize) %>
|
33
|
+
</td>
|
34
|
+
|
35
|
+
<td>
|
36
|
+
<%= event.created_at %>
|
37
|
+
</td>
|
38
|
+
</tr>
|
39
|
+
<% end %>
|
40
|
+
</tbody>
|
41
|
+
</table>
|
42
|
+
<% end %>
|
@@ -5,6 +5,7 @@
|
|
5
5
|
<th><%= sort :host, :as => _("Owner") %></th>
|
6
6
|
<th><%= sort :type, :as => _("Type") %></th>
|
7
7
|
<th><%= sort :enabled, :as => _("Enabled") %></th>
|
8
|
+
<th class="col-md-2"><%= _('Actions') %></th>
|
8
9
|
</tr>
|
9
10
|
</thead>
|
10
11
|
<tbody>
|
@@ -12,7 +13,7 @@
|
|
12
13
|
<tr class="<%= lock.enabled? ? '' : 'warning' %>">
|
13
14
|
<td>
|
14
15
|
<%= icon_text(dlmlock_status_icon_class(lock),
|
15
|
-
link_to_if_authorized(lock.name,
|
16
|
+
link_to_if_authorized(lock.name, hash_for_foreman_dlm_dlmlock_path(:id => lock)),
|
16
17
|
kind: 'fa',
|
17
18
|
class: "#{dlmlock_status_icon_color_class(lock)} fa-lg")
|
18
19
|
%>
|
@@ -38,6 +39,7 @@
|
|
38
39
|
<%= icon_text('toggle-off', 'Disabled', {kind: 'fa', class: 'center fa-lg', title: _('Disabled')}) %>
|
39
40
|
<% end %>
|
40
41
|
</td>
|
42
|
+
<td><%= action_buttons(*dlmlock_actions(lock, authorizer)) %></td>
|
41
43
|
</tr>
|
42
44
|
<% end %>
|
43
45
|
</tbody>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% title @dlmlock.name %>
|
2
|
+
<% breadcrumbs(
|
3
|
+
resource_url: api_dlmlocks_path
|
4
|
+
) if respond_to?(:breadcrumbs) # Requires Foreman >= 1.18 %>
|
5
|
+
|
6
|
+
<%= title_actions link_to(_('Back'), foreman_dlm_dlmlocks_path, :class => 'btn btn-default'),
|
7
|
+
((link_to(_("Host details"), @dlmlock.host, :class => 'btn btn-default') if @dlmlock.host.present?))
|
8
|
+
%>
|
9
|
+
|
10
|
+
<%= render 'details' %>
|
@@ -6,9 +6,9 @@
|
|
6
6
|
<p>
|
7
7
|
<%= _('You don\'t seem to have any locks.') %></br>
|
8
8
|
<%= _('The distributed lock manager allows you to automatically schedule system updates across a cluster of hosts.') %>
|
9
|
-
<%= link_to _('Learn more about this in the documentation.'), 'https://github.com/
|
9
|
+
<%= link_to _('Learn more about this in the documentation.'), 'https://github.com/dm-drogeriemarkt/foreman_dlm', :rel => "external" %>.
|
10
10
|
</p>
|
11
11
|
<div class="blank-slate-pf-main-action">
|
12
|
-
<%= link_to _('Documentation'), 'https://github.com/
|
12
|
+
<%= link_to _('Documentation'), 'https://github.com/dm-drogeriemarkt/foreman_dlm', :rel => 'external', :class => 'btn btn-primary btn-lg' %>
|
13
13
|
</div>
|
14
14
|
</div>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<% if @host.dlmlocks.any? %>
|
2
|
+
<%= alert class: 'alert-info',
|
3
|
+
header: '',
|
4
|
+
text: n_(
|
5
|
+
'This host holds one lock.',
|
6
|
+
'This host holds %s locks.',
|
7
|
+
@host.dlmlocks.count
|
8
|
+
) % @host.dlmlocks.count
|
9
|
+
%>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<table class="<%= table_css_classes %>">
|
13
|
+
<thead>
|
14
|
+
<tr>
|
15
|
+
<th colspan="2"><%= _('Locks') %></th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
<tbody>
|
19
|
+
<tr>
|
20
|
+
<td class="text-nowrap"><%= _('Last check-in') %></td>
|
21
|
+
<td><%= @host.dlm_facet && @host.dlm_facet.last_checkin_at ? date_time_relative(@host.dlm_facet.last_checkin_at) : _('N/A') %></td>
|
22
|
+
</tr>
|
23
|
+
<tr>
|
24
|
+
<td><%= _('Holds Locks') %></td>
|
25
|
+
<td>
|
26
|
+
<% if @host.dlmlocks.any? %>
|
27
|
+
<% @host.dlmlocks.authorized(:view_dlmlocks).each do |lock| %>
|
28
|
+
<%= link_to_if_authorized(lock.name, hash_for_foreman_dlm_dlmlock_path(lock)) %>
|
29
|
+
<span class="label label-<%= lock.updated_at > 6.hours.ago ? 'info' : 'warning' %>">
|
30
|
+
<%= _('acquired') %> <%= date_time_relative_value(lock.updated_at) %>
|
31
|
+
</span>
|
32
|
+
<% end %>
|
33
|
+
<% else %>
|
34
|
+
<%= _('None') %>
|
35
|
+
<% end %>
|
36
|
+
</td>
|
37
|
+
</tr>
|
38
|
+
</tbody>
|
39
|
+
</table>
|
data/config/routes.rb
CHANGED
@@ -1,24 +1,31 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
namespace :api, :defaults => { :format => 'json' } do
|
3
3
|
scope '(:apiv)', :module => :v2,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
4
|
+
:defaults => { :apiv => 'v2' },
|
5
|
+
:apiv => /v1|v2/,
|
6
|
+
:constraints => ApiConstraints.new(:version => 2, :default => true) do
|
7
|
+
constraints(id: /[^\/]+/) do
|
8
|
+
resources :dlmlocks, only: [:index, :show, :update, :destroy] do
|
9
|
+
resources :dlmlock_events, only: [:index]
|
10
|
+
|
11
|
+
get :lock, on: :member, action: :show, controller: 'dlmlocks'
|
12
|
+
put :lock, on: :member, action: :acquire, controller: 'dlmlocks'
|
13
|
+
delete :lock, on: :member, action: :release, controller: 'dlmlocks'
|
13
14
|
end
|
14
|
-
resources :dlmlocks, only: [:create]
|
15
15
|
end
|
16
|
+
resources :dlmlocks, only: [:create]
|
17
|
+
end
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
resources :dlmlocks, only: [:index, :show] do
|
20
|
+
namespace :foreman_dlm do
|
21
|
+
resources :dlmlocks, only: [:index, :show, :destroy] do
|
20
22
|
collection do
|
21
|
-
get
|
23
|
+
get :auto_complete_search
|
24
|
+
end
|
25
|
+
member do
|
26
|
+
put :enable
|
27
|
+
put :disable
|
28
|
+
put :release
|
22
29
|
end
|
23
30
|
end
|
24
31
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
[Unit]
|
2
|
+
Description=Clean up expired Foreman DLM events
|
3
|
+
Documentation=https://github.com/dm-drogeriemarkt/foreman_dlm/blob/master/README.md
|
4
|
+
Requires=network.target
|
5
|
+
|
6
|
+
[Service]
|
7
|
+
Type=oneshot
|
8
|
+
EnvironmentFile=-/etc/sysconfig/foreman_dlm
|
9
|
+
ExecStart=/sbin/foreman-rake dlmlocks:expire
|
10
|
+
TimeoutSec=30m
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class RenameDlmlockStiModels < ActiveRecord::Migration[5.1]
|
2
|
+
def up
|
3
|
+
execute "UPDATE dlmlocks set type='ForemanDlm::Dlmlock::Update' where type='Dlmlock::Update';"
|
4
|
+
end
|
5
|
+
|
6
|
+
def down
|
7
|
+
execute "UPDATE dlmlocks set type='Dlmlock::Update' where type='ForemanDlm::Dlmlock::Update';"
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AddDlmlockEvents < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
create_table :dlmlock_events do |t|
|
4
|
+
t.integer :dlmlock_id, index: true, null: false
|
5
|
+
t.string :event_type, index: true
|
6
|
+
t.integer :host_id, index: true
|
7
|
+
t.integer :user_id
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class CreateDlmFacets < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
create_table :dlm_facets do |t|
|
4
|
+
t.references :host, null: false, foreign_key: true, index: true, unique: true
|
5
|
+
t.column :last_checkin_at, :datetime
|
6
|
+
|
7
|
+
t.timestamps null: false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class UpdatePermissionsForScopedModels < ActiveRecord::Migration[5.1]
|
2
|
+
class FakePermission < ApplicationRecord
|
3
|
+
self.table_name = 'permissions'
|
4
|
+
end
|
5
|
+
|
6
|
+
def up
|
7
|
+
FakePermission.where(resource_type: 'Dlmlock').update_all(resource_type: 'ForemanDlm::Dlmlock')
|
8
|
+
end
|
9
|
+
|
10
|
+
def down
|
11
|
+
FakePermission.where(resource_type: 'ForemanDlm::Dlmlock').update_all(resource_type: 'Dlmlock')
|
12
|
+
end
|
13
|
+
end
|
data/lib/foreman_dlm/engine.rb
CHANGED
@@ -4,6 +4,7 @@ module ForemanDlm
|
|
4
4
|
|
5
5
|
config.autoload_paths += Dir["#{config.root}/app/controllers/concerns"]
|
6
6
|
config.autoload_paths += Dir["#{config.root}/app/models/concerns"]
|
7
|
+
config.autoload_paths += Dir["#{config.root}/app/jobs"]
|
7
8
|
|
8
9
|
# Add any db migrations
|
9
10
|
initializer 'foreman_dlm.load_app_instance_data' do |app|
|
@@ -14,63 +15,101 @@ module ForemanDlm
|
|
14
15
|
|
15
16
|
initializer 'foreman_dlm.register_plugin', :before => :finisher_hook do |_app|
|
16
17
|
Foreman::Plugin.register :foreman_dlm do
|
17
|
-
requires_foreman '>=
|
18
|
+
requires_foreman '>= 3.0'
|
18
19
|
|
19
20
|
apipie_documented_controllers ["#{ForemanDlm::Engine.root}/app/controllers/api/v2/*.rb"]
|
20
21
|
|
22
|
+
settings do
|
23
|
+
category(:general) do
|
24
|
+
setting('dlm_stale_time',
|
25
|
+
type: :integer,
|
26
|
+
default: 4,
|
27
|
+
description: N_('Number of hours after which locked Distributed Lock is stale'),
|
28
|
+
full_name: N_('Distributed Lock stale time'),
|
29
|
+
validate: { numericality: { greater_than: 0 } })
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
21
33
|
# Add permissions
|
22
34
|
security_block :foreman_dlm do
|
23
35
|
permission :view_dlmlocks, {
|
24
|
-
:dlmlocks => [:index, :show, :auto_complete_search],
|
36
|
+
:'foreman_dlm/dlmlocks' => [:index, :show, :auto_complete_search],
|
25
37
|
:'api/v2/dlmlocks' => [:index, :show]
|
26
|
-
}, :resource_type => 'Dlmlock'
|
38
|
+
}, :resource_type => 'ForemanDlm::Dlmlock'
|
27
39
|
|
28
40
|
permission :create_dlmlocks, {
|
29
41
|
:'api/v2/dlmlocks' => [:create]
|
30
|
-
}, :resource_type => 'Dlmlock'
|
42
|
+
}, :resource_type => 'ForemanDlm::Dlmlock'
|
31
43
|
|
32
44
|
permission :edit_dlmlocks, {
|
45
|
+
:'foreman_dlm/dlmlocks' => [:release, :enable, :disable],
|
33
46
|
:'api/v2/dlmlocks' => [:update, :acquire, :release]
|
34
|
-
}, :resource_type => 'Dlmlock'
|
47
|
+
}, :resource_type => 'ForemanDlm::Dlmlock'
|
35
48
|
|
36
49
|
permission :destroy_dlmlocks, {
|
50
|
+
:'foreman_dlm/dlmlocks' => [:destroy],
|
37
51
|
:'api/v2/dlmlocks' => [:destroy]
|
38
|
-
}, :resource_type => 'Dlmlock'
|
52
|
+
}, :resource_type => 'ForemanDlm::Dlmlock'
|
53
|
+
|
54
|
+
permission :view_dlmlock_events, {
|
55
|
+
:'api/v2/dlmlock_events' => [:index]
|
56
|
+
}, :resource_type => 'ForemanDlm::DlmlockEvent'
|
39
57
|
end
|
40
58
|
|
41
59
|
# Add a new role called 'Distributed Lock Manager' if it doesn't exist
|
42
|
-
role 'Distributed Lock Manager', [:view_dlmlocks,
|
60
|
+
role 'Distributed Lock Manager', [:view_dlmlocks,
|
61
|
+
:create_dlmlocks,
|
62
|
+
:edit_dlmlocks,
|
63
|
+
:destroy_dlmlocks,
|
64
|
+
:view_dlmlock_events],
|
65
|
+
'Role granting full access permissions to distributed locks'
|
43
66
|
|
44
67
|
# add menu entry
|
45
|
-
menu :top_menu, :
|
46
|
-
url_hash: { controller: :'dlmlocks', action: :index },
|
68
|
+
menu :top_menu, :foreman_dlm_dlmlocks,
|
69
|
+
url_hash: { controller: :'foreman_dlm/dlmlocks', action: :index },
|
47
70
|
caption: N_('Distributed Locks'),
|
48
71
|
parent: :monitor_menu,
|
49
72
|
after: :audits
|
73
|
+
|
74
|
+
# Dlm Facet
|
75
|
+
register_facet(ForemanDlm::DlmFacet, :dlm_facet) do
|
76
|
+
api_view list: 'foreman_dlm/api/v2/dlm_facets/base_with_root', single: 'foreman_dlm/api/v2/dlm_facets/show'
|
77
|
+
end
|
78
|
+
|
79
|
+
register_custom_status HostStatus::DlmlockStatus
|
80
|
+
|
81
|
+
# extend host show page
|
82
|
+
extend_page('hosts/show') do |context|
|
83
|
+
context.add_pagelet :main_tabs,
|
84
|
+
:name => N_('Locks'),
|
85
|
+
:partial => 'hosts/dlmlocks_tab',
|
86
|
+
:onlyif => proc { |host| host.dlm_facet }
|
87
|
+
end
|
50
88
|
end
|
51
89
|
end
|
52
90
|
|
53
91
|
# Include concerns in this config.to_prepare block
|
54
92
|
config.to_prepare do
|
55
|
-
|
56
|
-
|
93
|
+
Host::Managed.include ForemanDlm::HostExtensions
|
94
|
+
User.include ForemanDlm::UserExtensions
|
95
|
+
Host::Managed.include ForemanDlm::DlmFacetHostExtensions
|
57
96
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
rescue => e
|
62
|
-
Rails.logger.warn "ForemanDlm: skipping engine hook (#{e})"
|
63
|
-
end
|
97
|
+
Host::Managed.include ForemanDlm::HostMonitoringExtensions if ForemanDlm.with_monitoring?
|
98
|
+
rescue StandardError => e
|
99
|
+
Rails.logger.warn "ForemanDlm: skipping engine hook (#{e})"
|
64
100
|
end
|
65
101
|
|
66
102
|
initializer 'foreman_dlm.register_gettext', after: :load_config_initializers do |_app|
|
67
|
-
locale_dir = File.join(File.expand_path('
|
103
|
+
locale_dir = File.join(File.expand_path('../..', __dir__), 'locale')
|
68
104
|
locale_domain = 'foreman_dlm'
|
69
105
|
Foreman::Gettext::Support.add_text_domain locale_domain, locale_dir
|
70
106
|
end
|
71
107
|
end
|
72
108
|
|
73
109
|
def self.with_monitoring?
|
74
|
-
|
110
|
+
ForemanMonitoring # rubocop:disable Lint/Void
|
111
|
+
true
|
112
|
+
rescue StandardError
|
113
|
+
false
|
75
114
|
end
|
76
115
|
end
|
data/lib/foreman_dlm/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
desc <<-TASK_DESCRIPTION
|
2
|
+
Expire lock events automatically
|
3
|
+
|
4
|
+
Available conditions:
|
5
|
+
* days => number of days to keep reports (defaults to 14)
|
6
|
+
* batch_size => number of records deleted in single SQL transaction (defaults to 1k)
|
7
|
+
* sleep_time => delay in seconds between batches (defaults to 0.2)
|
8
|
+
|
9
|
+
TASK_DESCRIPTION
|
10
|
+
|
11
|
+
namespace :dlmlocks do
|
12
|
+
task expire: :environment do
|
13
|
+
created_before = ENV['days'].to_i.days if ENV['days']
|
14
|
+
batch_size = ENV['batch_size'].to_i if ENV['batch_size']
|
15
|
+
sleep_time = ENV['sleep_time'].to_f if ENV['sleep_time']
|
16
|
+
|
17
|
+
ForemanDlm::DlmlockEvent.expire(created_before: created_before, batch_size: batch_size, sleep_time: sleep_time)
|
18
|
+
end
|
19
|
+
end
|