dctl 1.0.2 → 1.0.3
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.
- data/CHANGELOG +9 -0
- data/README +6 -3
- data/TODO +1 -0
- data/lib/dctl.rb +1 -1
- data/lib/dctl/cmdparser.rb +1 -1
- data/lib/dctl/command.rb +30 -44
- data/lib/dctl/daemon.rb +10 -7
- data/lib/dctl/defaults.rb +4 -4
- data/lib/dctl/metainf.rb +1 -1
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
*1.0.3* (20th April, 2005) Bruno Carnazzi <mailto:bcarnazzi@gmail.com>
|
2
|
+
* added a new daemon state : unhandled
|
3
|
+
* status with no arg gives all daemon states
|
4
|
+
* status is the default command when no command is given
|
5
|
+
* status can handle multiple args, each as a daemon to check
|
6
|
+
* environment variables DCTL_DIR, DCTL_IN, DCTL_OUT, DCTL_ERR now override defaults
|
7
|
+
* strongly refactored command hierarchy
|
8
|
+
* added some examples
|
9
|
+
|
1
10
|
*1.0.2* (18th April, 2005) Bruno Carnazzi <mailto:bcarnazzi@gmail.com>
|
2
11
|
* better gem dependency support for cmdparse (>=1.0.1 required)
|
3
12
|
* added a check for incomplete command
|
data/README
CHANGED
@@ -9,7 +9,7 @@ It is designed to be small and smart ("less-is-more" philosophy), generic, and w
|
|
9
9
|
Major features:
|
10
10
|
* Convert any executable file with endless lifecycle into a controllable daemon
|
11
11
|
* Automatic handling of pidfiles
|
12
|
-
* Command-oriented style (dctl requires cmdparser)
|
12
|
+
* Command-oriented style (dctl requires cmdparser >= 1.0.1)
|
13
13
|
|
14
14
|
|
15
15
|
== Examples
|
@@ -17,12 +17,15 @@ Major features:
|
|
17
17
|
=== Start a daemon with redirection of stdout in file 'out'
|
18
18
|
% dctl start -oout test/infinite.sh
|
19
19
|
|
20
|
-
=== Get the status of
|
21
|
-
% dctl status test/infinite.sh
|
20
|
+
=== Get the status of some daemons (here, infinite.sh and sleep)
|
21
|
+
% dctl status test/infinite.sh sleep
|
22
22
|
|
23
23
|
=== Stop a daemon
|
24
24
|
% dctl stop test/infinite.sh
|
25
25
|
|
26
|
+
=== Get the status of all daemons
|
27
|
+
% dctl
|
28
|
+
|
26
29
|
|
27
30
|
== Download
|
28
31
|
|
data/TODO
CHANGED
data/lib/dctl.rb
CHANGED
data/lib/dctl/cmdparser.rb
CHANGED
@@ -31,7 +31,7 @@ module Dctl
|
|
31
31
|
cmd_parser.add_command Dctl::Command::RunCommand.new
|
32
32
|
cmd_parser.add_command Dctl::Command::RestartCommand.new
|
33
33
|
cmd_parser.add_command Dctl::Command::ZapCommand.new
|
34
|
-
cmd_parser.add_command Dctl::Command::StatusCommand.new
|
34
|
+
cmd_parser.add_command Dctl::Command::StatusCommand.new, true
|
35
35
|
cmd_parser.add_command CommandParser::HelpCommand.new
|
36
36
|
cmd_parser.add_command CommandParser::VersionCommand.new
|
37
37
|
|
data/lib/dctl/command.rb
CHANGED
@@ -14,9 +14,15 @@ module Dctl
|
|
14
14
|
# This module contains all possible commands allowed by Dctl
|
15
15
|
module Command
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
class SmartCommand < CommandParser::Command
|
18
|
+
def initialize
|
19
|
+
super self.class.to_s.gsub(/\w+::/, '').gsub(/Command$/, '').downcase
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class RedirectibleCommand < SmartCommand
|
24
|
+
def initialize
|
25
|
+
super
|
20
26
|
@stdin = $IN
|
21
27
|
@stdout = $OUT
|
22
28
|
@stderr = $ERR
|
@@ -26,15 +32,15 @@ module Dctl
|
|
26
32
|
options.on('-e', '--stderr FILE', "Use FILE as stderr when daemonized (default is '#{@stderr}').") { |@stderr| }
|
27
33
|
end
|
28
34
|
end
|
29
|
-
|
30
|
-
class StartCommand < CommandParser::Command
|
31
|
-
include Redirectible
|
32
35
|
|
36
|
+
class NonRedirectibleCommand < SmartCommand
|
33
37
|
def initialize
|
34
|
-
super
|
35
|
-
|
38
|
+
super
|
39
|
+
options.separator "Options:"
|
36
40
|
end
|
37
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
class StartCommand < RedirectibleCommand
|
38
44
|
def description
|
39
45
|
'Start a new daemonized instance of a specified application.'
|
40
46
|
end
|
@@ -46,14 +52,7 @@ module Dctl
|
|
46
52
|
end
|
47
53
|
end
|
48
54
|
|
49
|
-
class RestartCommand <
|
50
|
-
include Redirectible
|
51
|
-
|
52
|
-
def initialize
|
53
|
-
super 'restart'
|
54
|
-
std_init
|
55
|
-
end
|
56
|
-
|
55
|
+
class RestartCommand < RedirectibleCommand
|
57
56
|
def description
|
58
57
|
'Restart a daemonized instance of a specified application with new arguments.'
|
59
58
|
end
|
@@ -65,12 +64,7 @@ module Dctl
|
|
65
64
|
end
|
66
65
|
end
|
67
66
|
|
68
|
-
class StopCommand <
|
69
|
-
def initialize
|
70
|
-
super 'stop'
|
71
|
-
options.separator "Options:"
|
72
|
-
end
|
73
|
-
|
67
|
+
class StopCommand < NonRedirectibleCommand
|
74
68
|
def description
|
75
69
|
'Stop a daemonized instance of a specified application.'
|
76
70
|
end
|
@@ -81,12 +75,7 @@ module Dctl
|
|
81
75
|
end
|
82
76
|
end
|
83
77
|
|
84
|
-
class ZapCommand <
|
85
|
-
def initialize
|
86
|
-
super 'zap'
|
87
|
-
options.separator "Options:"
|
88
|
-
end
|
89
|
-
|
78
|
+
class ZapCommand < NonRedirectibleCommand
|
90
79
|
def description
|
91
80
|
"Manually set a daemonized instance of a specified application to 'stopped' state."
|
92
81
|
end
|
@@ -97,12 +86,7 @@ module Dctl
|
|
97
86
|
end
|
98
87
|
end
|
99
88
|
|
100
|
-
class RunCommand <
|
101
|
-
def initialize
|
102
|
-
super 'run'
|
103
|
-
options.separator "Options:"
|
104
|
-
end
|
105
|
-
|
89
|
+
class RunCommand < NonRedirectibleCommand
|
106
90
|
def description
|
107
91
|
'Run a new un-daemonized instance of a specified application.'
|
108
92
|
end
|
@@ -114,19 +98,21 @@ module Dctl
|
|
114
98
|
end
|
115
99
|
end
|
116
100
|
|
117
|
-
class StatusCommand <
|
118
|
-
def initialize
|
119
|
-
super 'status'
|
120
|
-
options.separator "Options:"
|
121
|
-
end
|
122
|
-
|
101
|
+
class StatusCommand < NonRedirectibleCommand
|
123
102
|
def description
|
124
|
-
"Get the state of
|
103
|
+
"Get the state of specified applications (one or more)."
|
125
104
|
end
|
126
105
|
|
127
106
|
def execute(cmd_parser, args)
|
128
|
-
|
129
|
-
|
107
|
+
if args.length > 0
|
108
|
+
args.each { |cmd| puts status(cmd) rescue puts $! }
|
109
|
+
else
|
110
|
+
Dir[File.join($DIR, '*.pid')].collect { |p| File.basename(p, '.*')}.each { |cmd| puts status(cmd) } # BUG ! if cmd not in PATH !
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def status(cmd)
|
115
|
+
"#{cmd}: #{File.basename(Dctl::Daemon.new(cmd, $DIR, false).status.id2name)}"
|
130
116
|
end
|
131
117
|
end
|
132
118
|
|
data/lib/dctl/daemon.rb
CHANGED
@@ -7,11 +7,13 @@ module Dctl
|
|
7
7
|
class Daemon
|
8
8
|
include Daemonize
|
9
9
|
|
10
|
-
def initialize(cmd, pidpath)
|
11
|
-
@app_path = Daemon::which(cmd) ||
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
def initialize(cmd, pidpath, check=true)
|
11
|
+
@app_path = File.expand_path(Daemon::which(cmd) || cmd)
|
12
|
+
if check
|
13
|
+
raise Errno::EISDIR, @app_path if File.directory? @app_path
|
14
|
+
raise Errno::ENOENT, @app_path until File.file? @app_path
|
15
|
+
raise Errno::EACCES, @app_path until File.executable? @app_path
|
16
|
+
end
|
15
17
|
@pidfile = PidFile.new pidpath, File.basename(cmd)
|
16
18
|
end
|
17
19
|
|
@@ -45,8 +47,9 @@ module Dctl
|
|
45
47
|
end
|
46
48
|
|
47
49
|
def status
|
48
|
-
|
49
|
-
|
50
|
+
(pid = @pidfile.read) rescue return :unhandled
|
51
|
+
Process.kill 0, pid rescue return :not_running
|
52
|
+
:running
|
50
53
|
end
|
51
54
|
end
|
52
55
|
|
data/lib/dctl/defaults.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# This file contains Dctl default values.
|
2
2
|
|
3
|
-
$DIR = Process.uid == 0 ? '/var/run' : '.'
|
3
|
+
$DIR = ENV['DCTL_DIR'] || (Process.uid == 0 ? '/var/run' : '.')
|
4
4
|
|
5
|
-
$IN = '/dev/null'
|
6
|
-
$OUT = '/dev/null'
|
7
|
-
$ERR = '/dev/null'
|
5
|
+
$IN = ENV['DCTL_IN'] || '/dev/null'
|
6
|
+
$OUT = ENV['DCTL_OUT'] || '/dev/null'
|
7
|
+
$ERR = ENV['DCTL_ERR'] || '/dev/null'
|
data/lib/dctl/metainf.rb
CHANGED
metadata
CHANGED