ducksboard_reporter 0.1.1 → 0.1.2
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/bin/ducksboard-reporter +20 -0
- data/lib/ducksboard_reporter/version.rb +1 -1
- data/lib/rund.rb +192 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f166259ade7200cbecbe4b6c47afebab9ec0168
|
4
|
+
data.tar.gz: b4c7a1700503fb55d363461d70069f35f39fafc4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9c0f3bacc413c914382430327ed53dc1e23eacb800aa69c0c363c6fc667b70261d77e1a8393775b6bd8d9ac210581155ac285a9776fc0a52669aab5432154ac
|
7
|
+
data.tar.gz: 7a83efa936333b143b766f3df60043a858ba3623a66a0517779362ab74c349e562a5ab6cf8b03fe9ae91ac317c1cb1b5e69b1d3f3c1582085947886a1a37c429
|
data/bin/ducksboard-reporter
CHANGED
@@ -4,10 +4,30 @@ $:.unshift File.expand_path("../../lib", __FILE__)
|
|
4
4
|
require "ducksboard_reporter"
|
5
5
|
require "trollop"
|
6
6
|
require "yaml"
|
7
|
+
require "rund"
|
7
8
|
|
8
9
|
opts = Trollop::options do
|
9
10
|
opt :config_file, "Path to config file", short: "f", type: :string, required: true
|
11
|
+
opt :pid_file, "Path to pid file", short: "p", type: :string
|
12
|
+
opt :log_file, "Path to log file", short: "l", type: :string
|
13
|
+
opt :run_dir, "Path to run dir", type: :string
|
14
|
+
opt :user, "The daemon wil run as specified user", type: :string
|
15
|
+
opt :group, "The daemon wil run as specified group", type: :string
|
16
|
+
opt :daemonize, "Detach from terminal", short: "d", default: false
|
10
17
|
end
|
11
18
|
|
19
|
+
# Rund.debug = true
|
20
|
+
|
12
21
|
config = YAML.load_file(opts[:config_file])
|
22
|
+
|
23
|
+
if opts[:daemonize]
|
24
|
+
Rund.pid_file = opts[:pid_file]
|
25
|
+
Rund.log_file = opts[:log_file]
|
26
|
+
Rund.run_dir = opts[:run_dir]
|
27
|
+
Rund.user = opts[:user]
|
28
|
+
Rund.group = opts[:group]
|
29
|
+
Rund.daemonize!
|
30
|
+
end
|
31
|
+
|
13
32
|
DucksboardReporter::App.new(config).start
|
33
|
+
|
data/lib/rund.rb
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "etc"
|
3
|
+
|
4
|
+
module Rund
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def daemonize!
|
8
|
+
# Keeep $stderr IO to display error and debug messages until
|
9
|
+
# daemonizing is finished
|
10
|
+
keep_local_stderr
|
11
|
+
|
12
|
+
File.umask(0000)
|
13
|
+
Process.daemon(true, true)
|
14
|
+
change_group if @group
|
15
|
+
change_user if @user
|
16
|
+
write_pid if @pid_file
|
17
|
+
change_dir
|
18
|
+
redirect_input
|
19
|
+
redirect_output
|
20
|
+
|
21
|
+
close_local_stderr
|
22
|
+
end
|
23
|
+
|
24
|
+
def log_file=(path)
|
25
|
+
@log_file = clean_path(path)
|
26
|
+
end
|
27
|
+
|
28
|
+
def pid_file=(path)
|
29
|
+
@pid_file = clean_path(path)
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_dir=(path)
|
33
|
+
@run_dir = clean_path(path)
|
34
|
+
end
|
35
|
+
|
36
|
+
def input_file=(path)
|
37
|
+
@input_file = clean_path(path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def user=(user)
|
41
|
+
@user = user
|
42
|
+
end
|
43
|
+
|
44
|
+
def group=(group)
|
45
|
+
@group = group
|
46
|
+
end
|
47
|
+
|
48
|
+
def debug=(flag)
|
49
|
+
@debug = !!flag
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def change_user
|
55
|
+
error("Not running as root. Cannot change user of process.") if Process.uid != 0
|
56
|
+
begin
|
57
|
+
user = (@user.is_a? Integer) ? Etc.getpwuid(@user) : Etc.getpwnam(@user)
|
58
|
+
rescue ArgumentError
|
59
|
+
error("User #{@user} does not exist")
|
60
|
+
end
|
61
|
+
|
62
|
+
debug { "Changing user to #{user.name} UID=#{user.uid}" }
|
63
|
+
|
64
|
+
Process::UID.change_privilege(user.uid)
|
65
|
+
end
|
66
|
+
|
67
|
+
def change_group
|
68
|
+
error("Not running as root. Cannot change group of process.") if Process.uid != 0
|
69
|
+
begin
|
70
|
+
group = (@group.is_a? Integer) ? Etc.getgrgid(@group) : Etc.getgrnam(@group)
|
71
|
+
rescue ArgumentError
|
72
|
+
error("Group #{@group} does not exist")
|
73
|
+
end
|
74
|
+
|
75
|
+
debug { "Changing group to #{group.name} GID=#{group.gid}" }
|
76
|
+
|
77
|
+
begin
|
78
|
+
Process::GID.change_privilege(group.gid)
|
79
|
+
rescue Errno::EPERM
|
80
|
+
error("Cannot change to group #{group.name}. Permission denied.")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def keep_local_stderr
|
85
|
+
@stderr = $stderr.dup
|
86
|
+
@stderr.sync
|
87
|
+
end
|
88
|
+
|
89
|
+
def close_local_stderr
|
90
|
+
@stderr.close
|
91
|
+
end
|
92
|
+
|
93
|
+
def clean_path(path)
|
94
|
+
path = path.to_s.strip
|
95
|
+
path.empty? ? nil : File.absolute_path(path)
|
96
|
+
end
|
97
|
+
|
98
|
+
def change_dir
|
99
|
+
@run_dir ||= "/"
|
100
|
+
debug { "Changing to #{@run_dir} as run dir" }
|
101
|
+
Dir.chdir(@run_dir)
|
102
|
+
end
|
103
|
+
|
104
|
+
def redirect_output
|
105
|
+
@log_file ||= "/dev/null"
|
106
|
+
debug { "Logging to #{@log_file}" }
|
107
|
+
|
108
|
+
log_dir = File.dirname(@log_file)
|
109
|
+
error("Log file dir does not exist #{log_dir}") unless File.exists?(log_dir)
|
110
|
+
|
111
|
+
begin
|
112
|
+
unless File.exists?(@log_file)
|
113
|
+
FileUtils.touch(@log_file)
|
114
|
+
File.chmod(0644, @log_file)
|
115
|
+
end
|
116
|
+
rescue Errno::EACCES
|
117
|
+
error("Cannot write log file #{@log_file}. Permission denied.")
|
118
|
+
end
|
119
|
+
|
120
|
+
$stderr.reopen(@log_file, "a")
|
121
|
+
$stdout.reopen($stderr)
|
122
|
+
$stdout.sync = $stderr.sync = true
|
123
|
+
end
|
124
|
+
|
125
|
+
def redirect_input
|
126
|
+
@input_file ||= "/dev/null"
|
127
|
+
$stdin.reopen(@input_file, "r")
|
128
|
+
end
|
129
|
+
|
130
|
+
def write_pid
|
131
|
+
debug { "Writing pid to #{@pid_file}" }
|
132
|
+
|
133
|
+
begin
|
134
|
+
File.open(@pid_file, File::CREAT | File::EXCL | File::WRONLY) {|f| f.write("#{Process.pid}") }
|
135
|
+
rescue Errno::EACCES
|
136
|
+
error("Cannot write pid file #{@pid_file}. Permission denied.")
|
137
|
+
rescue Errno::EEXIST
|
138
|
+
check_pid
|
139
|
+
retry
|
140
|
+
end
|
141
|
+
|
142
|
+
at_exit do
|
143
|
+
begin
|
144
|
+
File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
|
145
|
+
rescue Errno::EACCES
|
146
|
+
debug { "Cannot delete pid file #{@pid_file}. Permission denied." }
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def pid_status
|
152
|
+
return :exited unless File.exists?(@pid_file)
|
153
|
+
return :dead if pid == 0
|
154
|
+
|
155
|
+
Process.kill(0, pid) # check process status
|
156
|
+
:running
|
157
|
+
rescue Errno::ESRCH
|
158
|
+
:dead
|
159
|
+
rescue Errno::EPERM
|
160
|
+
:not_owned
|
161
|
+
end
|
162
|
+
|
163
|
+
def check_pid
|
164
|
+
case pid_status
|
165
|
+
when :running, :not_owned
|
166
|
+
error("A process is already running with pid #{pid}")
|
167
|
+
when :dead
|
168
|
+
debug { "Deleting stale pid file" }
|
169
|
+
File.delete(@pid_file)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def pid
|
174
|
+
@pid ||= File.read(@pid_file).strip.to_i
|
175
|
+
end
|
176
|
+
|
177
|
+
def error(msg)
|
178
|
+
@stderr << "ERROR: #{msg}\n"
|
179
|
+
exit 1
|
180
|
+
end
|
181
|
+
|
182
|
+
def debug(msg = nil)
|
183
|
+
return unless @debug
|
184
|
+
msg = yield if block_given?
|
185
|
+
@stderr << "DEBUG: #{msg}\n"
|
186
|
+
end
|
187
|
+
|
188
|
+
def error(msg)
|
189
|
+
@stderr << "ERROR: #{msg}\n"
|
190
|
+
exit 1
|
191
|
+
end
|
192
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ducksboard_reporter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- unnu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -174,6 +174,7 @@ files:
|
|
174
174
|
- lib/ducksboard_reporter/reporters/random.rb
|
175
175
|
- lib/ducksboard_reporter/version.rb
|
176
176
|
- lib/ducksboard_reporter/widget.rb
|
177
|
+
- lib/rund.rb
|
177
178
|
- spec/ducksboard_reporter_spec.rb
|
178
179
|
- spec/reporter_spec.rb
|
179
180
|
- spec/spec_helper.rb
|