runit-man 2.4.0 → 2.4.1a1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -38,13 +38,19 @@ This tool can provide additional information or actions through it's Web page.
38
38
  ### View names and content of files that related to concrete service
39
39
 
40
40
  For each known runit service this tool looks for `./runit-man/files-to-view/` folder.
41
- Every symlink here will be shown as link to view target file content.
41
+ Every symlink there will be shown as link to view target file content.
42
42
 
43
43
  ### Show links that related to concrete service
44
44
 
45
45
  For each known runit service this tool looks for `./runit-man/urls-to-view/` folder.
46
46
  Every file ended with .url will be shown as link to view target location (location should be written as content of this file).
47
47
 
48
+ ### Indicate services with any of watched files are modified since service startup
49
+
50
+ For each known runit service this tool looks for `./runit-man/files-to-watch/` folder.
51
+ Symlink targets there will be tested for its mtime to be less than service start time.
52
+ Service will be indicated as dangerous (as red color) to restart if any watched file is modified since service startup.
53
+
48
54
  ### Show buttons that send signals to concrete service
49
55
 
50
56
  For each known runit service this tool looks for `./runit-man/allowed-signals/` folder.
@@ -39,6 +39,12 @@ runit-man -p 14500 -r
39
39
  Для каждого известного сервиса runit эта утилита просматривает каталог `./runit-man/files-to-view/`.
40
40
  Каждый симлинк в этом каталоге будет показан как ссылка на просмотр содержимого целевого файла.
41
41
 
42
+ ### Индикация сервисов, чьи файлы для наблюдения изменились после старта
43
+
44
+ Для каждого известного сервиса runit эта утилита просматривает каталог `./runit-man/files-to-watch/`.
45
+ Целевые файлы симлинков в этом каталоге будут проверяться на время последней модификации файла.
46
+ Сервис будет помечаться как опасный (красным цветом) в плане рестарта, если любой наблюдаемый файл изменился после старта сервиса.
47
+
42
48
  ### Показ ссылок, относящихся к конкретному сервису
43
49
 
44
50
  Для каждого известного сервиса runit эта утилита просматривает каталог `./runit-man/urls-to-view/`.
@@ -18,7 +18,7 @@ class ServiceInfo::Base
18
18
  data = {}
19
19
  [
20
20
  :name, :stat, :active?, :logged?, :switchable?,
21
- :log_file_location, :log_pid
21
+ :log_file_location, :log_pid, :restart_dangerous?
22
22
  ].each do |sym|
23
23
  data[sym] = send(sym)
24
24
  end
@@ -109,6 +109,13 @@ class ServiceInfo::Base
109
109
  []
110
110
  end
111
111
 
112
+ def restart_dangerous?
113
+ ! ! files_to_watch.detect do |file|
114
+ mtime = File.stat(file).mtime
115
+ mtime > @status.started_at
116
+ end
117
+ end
118
+
112
119
  def send_signal(signal)
113
120
  return unless supervise?
114
121
 
@@ -117,19 +124,27 @@ class ServiceInfo::Base
117
124
  end
118
125
  end
119
126
 
120
- def files_to_view
121
- return [] unless File.directory?(files_to_view_folder)
127
+ def symlinks_to_file_paths(dir_path)
128
+ return [] unless File.directory?(dir_path)
122
129
 
123
- Dir.entries(files_to_view_folder).select do |name|
124
- File.symlink?(File.join(files_to_view_folder, name))
130
+ Dir.entries(dir_path).select do |name|
131
+ File.symlink?(File.join(dir_path, name))
125
132
  end.map do |name|
126
133
  File.expand_path(
127
- File.readlink(File.join(files_to_view_folder, name)),
128
- files_to_view_folder
134
+ File.readlink(File.join(dir_path, name)),
135
+ dir_path
129
136
  )
130
137
  end.select do |file_path|
131
138
  File.file?(file_path)
132
- end
139
+ end
140
+ end
141
+
142
+ def files_to_view
143
+ symlinks_to_file_paths(files_to_view_folder)
144
+ end
145
+
146
+ def files_to_watch
147
+ symlinks_to_file_paths(files_to_watch_folder)
133
148
  end
134
149
 
135
150
  def urls_to_view
@@ -165,6 +180,10 @@ protected
165
180
  File.join(active_service_folder, 'runit-man', 'files-to-view')
166
181
  end
167
182
 
183
+ def files_to_watch_folder
184
+ File.join(active_service_folder, 'runit-man', 'files-to-watch')
185
+ end
186
+
168
187
  def urls_to_view_folder
169
188
  File.join(active_service_folder, 'runit-man', 'urls-to-view')
170
189
  end
@@ -1,43 +1,58 @@
1
+ # Represents service status in daemontools supervise format.
2
+ # @ note see runit's sv.c source code for details.
1
3
  class ServiceStatus
4
+ # Size of status data in bytes
2
5
  STATUS_SIZE = 20
3
- # state
6
+ # Service is down.
4
7
  S_DOWN = 0
8
+ # Service is running.
5
9
  S_RUN = 1
10
+ # Service is finishing.
6
11
  S_FINISH = 2
7
12
 
13
+ # Initializes serice status by binary data.
14
+ # @param [String] data Binary data of service status in daemontools supervise format.
8
15
  def initialize(data)
9
- # status in daemontools supervise format
10
- # look at runit's sv.c for details
11
16
  data = (!data.nil? && data.length == STATUS_SIZE) ? data : nil
12
17
 
13
18
  @raw = data.nil? ? nil : data.unpack('NNxxxxVxa1CC')
14
19
  end
15
20
 
21
+ # Is service inactive?
16
22
  def inactive?
17
23
  @raw.nil?
18
24
  end
19
25
 
26
+ # Is service down?
20
27
  def down?
21
28
  status_byte == S_DOWN
22
29
  end
23
30
 
31
+ # Is service running?
24
32
  def run?
25
33
  status_byte == S_RUN
26
34
  end
27
35
 
36
+ # Is service finishing?
28
37
  def finish?
29
38
  status_byte == S_FINISH
30
39
  end
31
40
 
41
+ # Gets service process id.
42
+ # @return [Fixnum] Process id.
32
43
  def pid
33
44
  @pid ||= down? ? nil : @raw[2]
34
45
  end
35
46
 
47
+ # Gets service start time.
48
+ # @return [Time] Service start time.
36
49
  def started_at
37
50
  # from TAI to Unix
38
51
  @started_at ||= @raw ? Time.at((@raw[0] << 32) + @raw[1] - 4611686018427387914) : nil
39
52
  end
40
53
 
54
+ # Gets service uptime in seconds.
55
+ # @return [Float] Service uptime in seconds if running; otherwise nil.
41
56
  def uptime
42
57
  @uptime ||= down? ? nil : Time.now - started_at
43
58
  end
@@ -1,6 +1,6 @@
1
1
  # runit-man namespace.
2
2
  module RunitMan
3
3
  # runit-man version.
4
- VERSION = '2.4.0'.freeze
4
+ VERSION = '2.4.1a1'.freeze
5
5
  end
6
6
 
@@ -20,6 +20,7 @@ form.service-action, form.service-signal
20
20
  span.inactive {color:gray;}
21
21
  span.down {color:#8a1f11;}
22
22
  span.run {color:#264409;}
23
+ span.danger {color:red;}
23
24
 
24
25
  #services { text-align: center; }
25
26
 
@@ -1,7 +1,9 @@
1
1
  - need_second_row = !service_info.files_to_view.empty? || !service_info.urls_to_view.empty?
2
2
  %tr{:class=> even_or_odd ? 'even' : 'odd'}
3
3
  %td{:rowspan=> need_second_row ? 2 : 1}= h(service_info.pid)
4
- %th{:scope=>"row"}= h(service_info.name)
4
+ %th{:scope=>"row"}
5
+ %span{:class=>service_info.restart_dangerous? ? "danger" : "ok"}
6
+ = h(service_info.name)
5
7
  %td= service_info.started_at ? service_info.started_at.utc : ''
6
8
  %td= service_info.uptime ? ('%.2f' % service_info.uptime) : ''
7
9
  %td= stat_subst(service_info.stat)
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runit-man
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
5
- prerelease:
4
+ version: 2.4.1a1
5
+ prerelease: 5
6
6
  platform: ruby
7
7
  authors:
8
8
  - Akzhan Abdulin
@@ -13,7 +13,7 @@ date: 2012-04-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: yajl-ruby
16
- requirement: &2153692900 !ruby/object:Gem::Requirement
16
+ requirement: &2160877420 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2153692900
24
+ version_requirements: *2160877420
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: haml
27
- requirement: &2153692360 !ruby/object:Gem::Requirement
27
+ requirement: &2160876900 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '3.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2153692360
35
+ version_requirements: *2160876900
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: sinatra
38
- requirement: &2153691880 !ruby/object:Gem::Requirement
38
+ requirement: &2160876320 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.3'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2153691880
46
+ version_requirements: *2160876320
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: sinatra-content-for2
49
- requirement: &2153691360 !ruby/object:Gem::Requirement
49
+ requirement: &2160875660 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.2.4
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2153691360
57
+ version_requirements: *2160875660
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: i18n
60
- requirement: &2153690820 !ruby/object:Gem::Requirement
60
+ requirement: &2160875100 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0.5'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2153690820
68
+ version_requirements: *2160875100
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: file-tail
71
- requirement: &2153690260 !ruby/object:Gem::Requirement
71
+ requirement: &2160874360 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 1.0.7
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *2153690260
79
+ version_requirements: *2160874360
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: rake
82
- requirement: &2153689620 !ruby/object:Gem::Requirement
82
+ requirement: &2160872720 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ~>
@@ -90,10 +90,10 @@ dependencies:
90
90
  version: 0.9.0
91
91
  type: :development
92
92
  prerelease: false
93
- version_requirements: *2153689620
93
+ version_requirements: *2160872720
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: rspec-core
96
- requirement: &2153688780 !ruby/object:Gem::Requirement
96
+ requirement: &2160872000 !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
99
  - - ! '>='
@@ -101,10 +101,10 @@ dependencies:
101
101
  version: '0'
102
102
  type: :development
103
103
  prerelease: false
104
- version_requirements: *2153688780
104
+ version_requirements: *2160872000
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: rspec-expectations
107
- requirement: &2153688140 !ruby/object:Gem::Requirement
107
+ requirement: &2160871240 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
110
  - - ! '>='
@@ -112,10 +112,10 @@ dependencies:
112
112
  version: '0'
113
113
  type: :development
114
114
  prerelease: false
115
- version_requirements: *2153688140
115
+ version_requirements: *2160871240
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: rr
118
- requirement: &2153686480 !ruby/object:Gem::Requirement
118
+ requirement: &2160870740 !ruby/object:Gem::Requirement
119
119
  none: false
120
120
  requirements:
121
121
  - - ! '>='
@@ -123,10 +123,10 @@ dependencies:
123
123
  version: '0'
124
124
  type: :development
125
125
  prerelease: false
126
- version_requirements: *2153686480
126
+ version_requirements: *2160870740
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: rack-test
129
- requirement: &2153685940 !ruby/object:Gem::Requirement
129
+ requirement: &2160870100 !ruby/object:Gem::Requirement
130
130
  none: false
131
131
  requirements:
132
132
  - - ! '>='
@@ -134,10 +134,10 @@ dependencies:
134
134
  version: '0'
135
135
  type: :development
136
136
  prerelease: false
137
- version_requirements: *2153685940
137
+ version_requirements: *2160870100
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: bundler
140
- requirement: &2153685060 !ruby/object:Gem::Requirement
140
+ requirement: &2160869460 !ruby/object:Gem::Requirement
141
141
  none: false
142
142
  requirements:
143
143
  - - ~>
@@ -148,10 +148,10 @@ dependencies:
148
148
  version: 1.0.10
149
149
  type: :development
150
150
  prerelease: false
151
- version_requirements: *2153685060
151
+ version_requirements: *2160869460
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: yard
154
- requirement: &2153683440 !ruby/object:Gem::Requirement
154
+ requirement: &2160868120 !ruby/object:Gem::Requirement
155
155
  none: false
156
156
  requirements:
157
157
  - - ~>
@@ -159,10 +159,10 @@ dependencies:
159
159
  version: 0.7.5
160
160
  type: :development
161
161
  prerelease: false
162
- version_requirements: *2153683440
162
+ version_requirements: *2160868120
163
163
  - !ruby/object:Gem::Dependency
164
164
  name: redcarpet
165
- requirement: &2153682560 !ruby/object:Gem::Requirement
165
+ requirement: &2160866780 !ruby/object:Gem::Requirement
166
166
  none: false
167
167
  requirements:
168
168
  - - ~>
@@ -170,7 +170,7 @@ dependencies:
170
170
  version: 1.17.2
171
171
  type: :development
172
172
  prerelease: false
173
- version_requirements: *2153682560
173
+ version_requirements: *2160866780
174
174
  description: ! 'Simple runit (http://smarden.org/runit/) web management tool with
175
175
  i18n.
176
176
 
@@ -265,16 +265,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
265
265
  version: '0'
266
266
  segments:
267
267
  - 0
268
- hash: -2528648994926986438
268
+ hash: 706955117803235190
269
269
  required_rubygems_version: !ruby/object:Gem::Requirement
270
270
  none: false
271
271
  requirements:
272
- - - ! '>='
272
+ - - ! '>'
273
273
  - !ruby/object:Gem::Version
274
- version: '0'
275
- segments:
276
- - 0
277
- hash: -2528648994926986438
274
+ version: 1.3.1
278
275
  requirements:
279
276
  - none
280
277
  rubyforge_project: