ducksboard_reporter 0.1.1 → 0.1.2

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: faaa03c65806c52554a5e2afe37b04914c1dccb6
4
- data.tar.gz: 7820258a49917f566545b8298760c2fc4461d448
3
+ metadata.gz: 0f166259ade7200cbecbe4b6c47afebab9ec0168
4
+ data.tar.gz: b4c7a1700503fb55d363461d70069f35f39fafc4
5
5
  SHA512:
6
- metadata.gz: 90b1b70ee0b2b8fc0b838b20a95b682ae024c2dd6a2b9f48cc43a944672a9dec9baee1fa842e8678fc1d07a125ac6d52461abb1c58a652f362ccc8fb10984075
7
- data.tar.gz: b1779d9639ce483333c7ee84429074c5e6e36033b5ed7c5fa7ee2c9455a7c5f80c7c53c7f53846ae5e5d85c5ef696cfc3138f57018e6f3422b1f72af7d0680b4
6
+ metadata.gz: e9c0f3bacc413c914382430327ed53dc1e23eacb800aa69c0c363c6fc667b70261d77e1a8393775b6bd8d9ac210581155ac285a9776fc0a52669aab5432154ac
7
+ data.tar.gz: 7a83efa936333b143b766f3df60043a858ba3623a66a0517779362ab74c349e562a5ab6cf8b03fe9ae91ac317c1cb1b5e69b1d3f3c1582085947886a1a37c429
@@ -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
+
@@ -1,3 +1,3 @@
1
1
  module DucksboardReporter
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
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.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-09-30 00:00:00.000000000 Z
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