rehctaw 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +41 -0
  3. data/bin/rehctaw +103 -0
  4. metadata +48 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 52bdd0357b77fbd19825f9cbe698a35ba024ba87
4
+ data.tar.gz: 1f584f7e65da9fa005c19b4aa3ecf886439ce991
5
+ SHA512:
6
+ metadata.gz: 3d7a13db6f39cdb4bfe59f47b0191eb538c08165084645f3830ecd2d61b4b9ea672fa835256b673c75d14775f519c21ce444ddd567ea4c6affb4d46375085d7c
7
+ data.tar.gz: 266fed86851ed1a113c1c53333f60138df14a502b7fcc2bc94c005f42b271a166ab082dbcc35716524bdbf7f53f71b66323eb479364bfcac4c8d6fe76e9fccb5
data/README.md ADDED
@@ -0,0 +1,41 @@
1
+ ## Name
2
+
3
+ `rehctaw` - Execute system commands according to file contents.
4
+
5
+ ## Description
6
+
7
+ `rehctaw` watches contents of a file, and executes system commands
8
+ according to those contents. The commands, intervals, ... are provided
9
+ in a YAML configuration file which is also watched.
10
+
11
+ ## Example
12
+
13
+ The sample configuration file can be found under `./examples/` directory.
14
+ To use this example, type
15
+
16
+ $ cp ./examples/simple.yaml ./examples/mine.yaml
17
+ $ ./bin/rehctaw ./examples/mine.yaml
18
+ $ echo foobar > /tmp/watcher
19
+ $ echo reload > /tmp/watcher
20
+
21
+ You can update the file `./examples/mine.yaml`. The program will use
22
+ new settings in the next run.
23
+
24
+ ## License
25
+
26
+ MIT
27
+
28
+ ## Author
29
+
30
+ Anh K. Huynh
31
+
32
+ ## History
33
+
34
+ The idea comes from some `Rails` framework. When a `Rails` application
35
+ is running, you can quickly send a `reload` signal to it, by touching
36
+ a file. See [ChiliProject][] for an example.
37
+
38
+ I don't want to use `inotify`, because that works at file system level
39
+ and it may cause some issues when the file is renamed.
40
+
41
+ [ChiliProject]: https://www.chiliproject.org/projects/chiliproject/wiki/Restart_ChiliProject
data/bin/rehctaw ADDED
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Purpose: Execute something according to contents of a file
4
+ # Author : Anh K. Huynh
5
+ # License: MIT
6
+ # Date : 2015 Feb 25
7
+
8
+ begin
9
+ require 'yaml'
10
+ require 'timeout'
11
+ rescue => e
12
+ STDERR.puts ":: Error: #{e}"
13
+ exit 127
14
+ end
15
+
16
+ GLOBAL_WATCHER = {
17
+ "mtime" => 0
18
+ }
19
+
20
+ _default_watcher = {
21
+ "interval" => 5,
22
+ "stop" => "/bin/true",
23
+ "start" => "/bin/true",
24
+ "restart" => "/bin/true",
25
+ "reset" => "/bin/true",
26
+ "action" => "",
27
+ "file" => "/dev/null",
28
+ "mtime" => 0,
29
+ "timeout" => 10
30
+ }
31
+
32
+ def _say(something)
33
+ STDERR.puts ":: #{something}"
34
+ end
35
+
36
+ def _configuration_rescan(watcher, config_file)
37
+ return watcher unless File.file?(config_file) and File.readable?(config_file)
38
+
39
+ new_mtime = File.stat(config_file).mtime.to_i
40
+
41
+ if new_mtime != GLOBAL_WATCHER["mtime"]
42
+ GLOBAL_WATCHER["mtime"] = new_mtime
43
+ begin
44
+ new_watcher = YAML.load_file(config_file)
45
+ watcher.merge!(new_watcher["watcher"])
46
+ watcher["interval"] = [1, watcher["interval"].to_i.abs].max
47
+ watcher["timeout"] = [1, watcher["timeout"].to_i.abs].max
48
+
49
+ _say "Info: Config reload => #{new_watcher.inspect}"
50
+ rescue => e
51
+ _say "Error: #{e}"
52
+ return watcher
53
+ end
54
+ end
55
+
56
+ return watcher
57
+ end
58
+
59
+ if ARGV.size < 1
60
+ _say "Error: Missing configuration file"
61
+ exit 127
62
+ end
63
+
64
+ GLOBAL_WATCHER["file"] = ARGV.first
65
+ watcher = _configuration_rescan(_default_watcher, GLOBAL_WATCHER["file"])
66
+
67
+ while true
68
+ executable = false
69
+
70
+ if File.file?(watcher["file"]) and File.readable?(watcher["file"])
71
+ new_mtime = File.stat(watcher["file"]).mtime.to_i
72
+ if new_mtime != watcher["mtime"]
73
+ executable = true if watcher["mtime"] > 0
74
+ watcher["mtime"] = new_mtime
75
+ # FIXME: reading the whole file may not a good idea. It's slow
76
+ # FIXME: should find a way to read the first line of a file.
77
+ new_action = File.readlines(watcher["file"]).first.to_s.strip
78
+ watcher["action"] = new_action
79
+ end
80
+ else
81
+ _say "Error: Action file '#{watcher["file"]}' unreadable"
82
+ end
83
+
84
+ if executable
85
+ if watcher[watcher["action"]]
86
+ command = watcher[watcher["action"]]
87
+ _say "Info: Executing (#{watcher["action"]}) '#{command}'"
88
+ begin
89
+ Timeout::timeout(watcher["timeout"]) do
90
+ ret = system("#{command}")
91
+ end
92
+ _say "Info: Execution complete"
93
+ rescue Timeout::Error => e
94
+ _say "Error: Timeout reachable (#{watcher["timeout"]}s)"
95
+ end
96
+ else
97
+ _say "Error: Invalid action: #{watcher["action"]}"
98
+ end
99
+ end
100
+
101
+ sleep(watcher["interval"])
102
+ watcher = _configuration_rescan(watcher, GLOBAL_WATCHER["file"])
103
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rehctaw
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Anh K. Huynh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "`rehctaw` watches contents of a file, and executes system commands according
14
+ to those contents. The commands, intervals, ... are provided in a YAML configuration
15
+ file which is also watched."
16
+ email: kyanh@theslinux.org
17
+ executables:
18
+ - rehctaw
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - README.md
23
+ - bin/rehctaw
24
+ homepage: https://github.com/icy/rehctaw
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.4.5
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: "`rehctaw` executes system commands according to file contents"
48
+ test_files: []