locd 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +108 -0
  3. data/.gitmodules +9 -0
  4. data/.qb-options.yml +4 -0
  5. data/.rspec +3 -0
  6. data/.travis.yml +5 -0
  7. data/.yardopts +7 -0
  8. data/Gemfile +10 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +72 -0
  11. data/Rakefile +6 -0
  12. data/VERSION +1 -0
  13. data/config/default.yml +24 -0
  14. data/doc/files/design/domains_and_labels.md +117 -0
  15. data/doc/files/topics/agents.md +16 -0
  16. data/doc/files/topics/launchd.md +15 -0
  17. data/doc/files/topics/plists.md +39 -0
  18. data/doc/include/plist.md +3 -0
  19. data/exe/locd +24 -0
  20. data/lib/locd.rb +75 -0
  21. data/lib/locd/agent.rb +1186 -0
  22. data/lib/locd/agent/job.rb +142 -0
  23. data/lib/locd/agent/proxy.rb +111 -0
  24. data/lib/locd/agent/rotate_logs.rb +82 -0
  25. data/lib/locd/agent/site.rb +174 -0
  26. data/lib/locd/agent/system.rb +270 -0
  27. data/lib/locd/cli.rb +4 -0
  28. data/lib/locd/cli/command.rb +9 -0
  29. data/lib/locd/cli/command/agent.rb +310 -0
  30. data/lib/locd/cli/command/base.rb +243 -0
  31. data/lib/locd/cli/command/job.rb +110 -0
  32. data/lib/locd/cli/command/main.rb +201 -0
  33. data/lib/locd/cli/command/proxy.rb +177 -0
  34. data/lib/locd/cli/command/rotate_logs.rb +152 -0
  35. data/lib/locd/cli/command/site.rb +47 -0
  36. data/lib/locd/cli/table.rb +157 -0
  37. data/lib/locd/config.rb +237 -0
  38. data/lib/locd/config/base.rb +93 -0
  39. data/lib/locd/errors.rb +65 -0
  40. data/lib/locd/label.rb +61 -0
  41. data/lib/locd/launchctl.rb +209 -0
  42. data/lib/locd/logging.rb +360 -0
  43. data/lib/locd/newsyslog.rb +402 -0
  44. data/lib/locd/pattern.rb +193 -0
  45. data/lib/locd/proxy.rb +272 -0
  46. data/lib/locd/proxymachine.rb +34 -0
  47. data/lib/locd/util.rb +49 -0
  48. data/lib/locd/version.rb +26 -0
  49. data/locd.gemspec +66 -0
  50. metadata +262 -0
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requirements
4
+ # =======================================================================
5
+
6
+ # Stdlib
7
+ # -----------------------------------------------------------------------
8
+ require 'shellwords'
9
+
10
+ # Deps
11
+ # -----------------------------------------------------------------------
12
+ require 'thor'
13
+
14
+ # Project / Package
15
+ # -----------------------------------------------------------------------
16
+
17
+
18
+ # Refinements
19
+ # =======================================================================
20
+
21
+ using NRSER
22
+ using NRSER::Types
23
+
24
+
25
+ # Definitions
26
+ # =======================================================================
27
+
28
+ # CLI interface using the `thor` gem.
29
+ #
30
+ # @see http://whatisthor.com/
31
+ #
32
+ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
33
+
34
+
35
+ # Helpers
36
+ # ============================================================================
37
+ #
38
+
39
+ def self.agent_class
40
+ Locd::Agent::Proxy
41
+ end
42
+
43
+
44
+ protected
45
+ # ========================================================================
46
+
47
+ def proxy
48
+ @proxy ||= begin
49
+ proxy = Locd::Agent::Proxy.get
50
+
51
+ if proxy.nil?
52
+ logger.error "Proxy agent plist not found",
53
+ expected_path: Locd::Agent::Proxy.plist_abs_path.to_s
54
+
55
+ logger.info "Run `locd setup` to create it."
56
+
57
+ exit 1
58
+ end
59
+
60
+ proxy
61
+ end
62
+ end
63
+
64
+ # end protected
65
+ public
66
+
67
+
68
+
69
+ # Commands
70
+ # ============================================================================
71
+
72
+ desc "setup",
73
+ "Add agents that runs a command in the current directory"
74
+ include_options groups: [:write, :add, :respond_with_agents]
75
+ def setup
76
+ agent = agent_class.add **option_kwds( groups: :write )
77
+
78
+ logger.info "`#{ agent.label }` agent created."
79
+
80
+ agent.load if options[:load]
81
+
82
+ respond agent
83
+ end
84
+
85
+
86
+ desc "run",
87
+ "Run the proxy server (in the foreground)"
88
+ method_option :bind,
89
+ desc: "Address to bind the proxy server to",
90
+ aliases: ['-b', '--host', '-h'],
91
+ type: :string,
92
+ default: Locd.config[:proxy, :bind]
93
+ method_option :port,
94
+ desc: "Port to run the proxy on",
95
+ aliases: '-p',
96
+ type: :numeric,
97
+ default: Locd.config[:proxy, :port]
98
+ def run_
99
+ Locd::Proxy.serve \
100
+ bind: options[:bind],
101
+ port: options[:port]
102
+ end
103
+
104
+
105
+ desc "port",
106
+ "Get port Loc'd proxy is running on or configured for"
107
+ def port
108
+ respond Locd::Proxy.port
109
+ end
110
+
111
+
112
+ # Agent Interface
113
+ # ----------------------------------------------------------------------------
114
+
115
+ desc 'status',
116
+ 'Print proxy status'
117
+ def status
118
+ respond \
119
+ label: proxy.label,
120
+ port: proxy.port,
121
+ status: proxy.status
122
+ end
123
+
124
+
125
+ desc "rm",
126
+ "Remove (uninstall, delete) the proxy agent"
127
+ map remove: :rm
128
+ def rm
129
+ proxy.remove
130
+ end
131
+
132
+
133
+ desc "plist",
134
+ "Show the proxy's launchd property list"
135
+ def plist
136
+ agent = proxy
137
+
138
+ if options[:json] || options[:yaml]
139
+ respond agent.plist
140
+ else
141
+ respond agent.path.read
142
+ end
143
+ end
144
+
145
+
146
+ desc "start",
147
+ "Start the proxy"
148
+ option :write,
149
+ desc: "Set `launchd` *Disabled* key to `false`",
150
+ type: :boolean
151
+ def start
152
+ proxy.start **option_kwds( :write )
153
+ end
154
+
155
+
156
+ desc "stop",
157
+ "Stop the proxy"
158
+ include_options groups: [:stop]
159
+ option :write,
160
+ desc: "Set `launchd` *Disabled* key to `true`",
161
+ type: :boolean
162
+ def stop
163
+ proxy.stop **option_kwds( :unload, groups: :stop )
164
+ end
165
+
166
+
167
+ desc "restart",
168
+ "Restart the proxy"
169
+ include_options groups: [:stop]
170
+ option :write,
171
+ desc: "Set `launchd` *Disabled* key to `false`",
172
+ type: :boolean
173
+ def restart
174
+ proxy.restart **option_kwds( :write, groups: :stop )
175
+ end
176
+
177
+ end # module Locd::CLI::Proxy
@@ -0,0 +1,152 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requirements
4
+ # =======================================================================
5
+
6
+ # Stdlib
7
+ # -----------------------------------------------------------------------
8
+ require 'shellwords'
9
+
10
+ # Deps
11
+ # -----------------------------------------------------------------------
12
+ require 'thor'
13
+
14
+ # Project / Package
15
+ # -----------------------------------------------------------------------
16
+
17
+
18
+ # Refinements
19
+ # =======================================================================
20
+
21
+ using NRSER
22
+ using NRSER::Types
23
+
24
+
25
+ # Definitions
26
+ # =======================================================================
27
+
28
+ # Manage log rotation.
29
+ #
30
+ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Agent
31
+
32
+
33
+ # Helpers
34
+ # ============================================================================
35
+ #
36
+
37
+ def self.agent_class
38
+ Locd::Agent::RotateLogs
39
+ end
40
+
41
+
42
+ protected
43
+ # ========================================================================
44
+
45
+ def agent
46
+ @agent ||= begin
47
+ agent = agent_class.get
48
+
49
+ if agent.nil?
50
+ logger.error "Agent plist not found",
51
+ expected_path: agent_class.plist_abs_path.to_s
52
+
53
+ logger.info "Run `locd setup` to create it."
54
+
55
+ exit 1
56
+ end
57
+
58
+ agent
59
+ end
60
+ end
61
+
62
+ # end protected
63
+ public
64
+
65
+
66
+ # Commands
67
+ # ============================================================================
68
+
69
+ desc "setup",
70
+ "Add agents that runs a command in the current directory"
71
+ include_options groups: [:write, :add, :respond_with_agents]
72
+ def setup
73
+ agent = agent_class.add **option_kwds( groups: :write )
74
+
75
+ logger.info "`#{ agent.label }` agent created."
76
+
77
+ agent.load if options[:load]
78
+
79
+ respond agent
80
+ end
81
+
82
+
83
+ desc "run",
84
+ "Rotate agent logs using `newsyslog`"
85
+ def run_
86
+ Locd::Newsyslog.run_all
87
+ end
88
+
89
+
90
+ # Agent Interface
91
+ # ----------------------------------------------------------------------------
92
+
93
+ desc 'status',
94
+ 'Print agent status'
95
+ def status
96
+ respond \
97
+ label: agent.label,
98
+ status: agent.status
99
+ end
100
+
101
+
102
+ desc "rm",
103
+ "Remove (uninstall, delete) the agent"
104
+ map remove: :rm
105
+ def rm
106
+ agent.remove
107
+ end
108
+
109
+
110
+ desc "plist",
111
+ "Show the agent's launchd property list"
112
+ def plist
113
+ if options[:json] || options[:yaml]
114
+ respond agent.plist
115
+ else
116
+ respond agent.path.read
117
+ end
118
+ end
119
+
120
+
121
+ desc "start",
122
+ "Start the agent"
123
+ option :write,
124
+ desc: "Set `launchd` *Disabled* key to `false`",
125
+ type: :boolean
126
+ def start
127
+ agent.start **option_kwds( :write )
128
+ end
129
+
130
+
131
+ desc "stop",
132
+ "Stop the agent"
133
+ include_options groups: [:stop]
134
+ option :write,
135
+ desc: "Set `launchd` *Disabled* key to `true`",
136
+ type: :boolean
137
+ def stop
138
+ agent.stop **option_kwds( :unload, groups: :stop )
139
+ end
140
+
141
+
142
+ desc "restart",
143
+ "Restart the agent"
144
+ include_options groups: [:stop]
145
+ option :write,
146
+ desc: "Set `launchd` *Disabled* key to `false`",
147
+ type: :boolean
148
+ def restart
149
+ agent.restart **option_kwds( :write, groups: :stop )
150
+ end
151
+
152
+ end # module Locd::CLI::RotateLogs
@@ -0,0 +1,47 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+
5
+ # Refinements
6
+ # =======================================================================
7
+
8
+ using NRSER
9
+ using NRSER::Types
10
+
11
+
12
+ # Definitions
13
+ # =======================================================================
14
+
15
+ # TODO Doc me pls
16
+ #
17
+ class Locd::CLI::Command::Site < Locd::CLI::Command::Agent
18
+
19
+ # Helpers
20
+ # ============================================================================
21
+ #
22
+
23
+ def self.agent_class
24
+ Locd::Agent::Site
25
+ end
26
+
27
+
28
+ protected
29
+ # ========================================================================
30
+
31
+ def agent_table agents
32
+ Locd::CLI::Table.build do |t|
33
+ t.col "PID", &:pid
34
+ t.col "LEC", desc: "Last Exit Code", &:last_exit_code
35
+ t.col "URL", &:url
36
+ t.col "Port", &:port
37
+ t.col "File" do |agent| agent_file agent end
38
+
39
+ t.rows agents
40
+ end
41
+ end
42
+
43
+ # end protected
44
+ public
45
+
46
+
47
+ end # class Locd::CLI::Command::Site
@@ -0,0 +1,157 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Requirements
4
+ # =======================================================================
5
+
6
+ # Stdlib
7
+ # -----------------------------------------------------------------------
8
+
9
+ # Deps
10
+ # -----------------------------------------------------------------------
11
+
12
+ # Project / Package
13
+ # -----------------------------------------------------------------------
14
+
15
+
16
+ # Refinements
17
+ # =======================================================================
18
+
19
+ using NRSER
20
+ using NRSER::Types
21
+
22
+
23
+ # Definitions
24
+ # =======================================================================
25
+
26
+ #
27
+ class Locd::CLI::Table
28
+ # Unicode superscript number to use as references for columns with
29
+ # descriptions.
30
+ #
31
+ # @return [Array<String>]
32
+ #
33
+ SUPERSCRIPT_NUMBERS = [
34
+ "\u2070",
35
+ "\u00B9",
36
+ "\u00B2",
37
+ "\u00B3",
38
+ "\u2070",
39
+ "\u2074",
40
+ "\u2075",
41
+ "\u2076",
42
+ "\u2077",
43
+ "\u2078",
44
+ "\u2079",
45
+ ].freeze
46
+
47
+ NULL = '␀'
48
+
49
+
50
+ # Mixins
51
+ # ============================================================================
52
+
53
+ include Enumerable
54
+ include NRSER::Ext::Enumerable
55
+
56
+
57
+ # Classes
58
+ # ============================================================================
59
+
60
+ # A column in a table.
61
+ #
62
+ class Column
63
+ attr_reader :name, :getter, :desc
64
+
65
+ def initialize name, desc: nil, &getter
66
+ @name = name
67
+ @getter = getter
68
+ @desc = desc
69
+ end
70
+ end # class Column
71
+
72
+
73
+ # @todo Document build method.
74
+ #
75
+ # @param [type] arg_name
76
+ # @todo Add name param description.
77
+ #
78
+ # @return [return_type]
79
+ # @todo Document return value.
80
+ #
81
+ def self.build &block
82
+ new.tap &block
83
+ end # .build
84
+
85
+ def initialize
86
+ @columns = []
87
+ @rows = []
88
+ end
89
+
90
+ def each &block
91
+ @rows.each &block
92
+ end
93
+
94
+ def each_index &block
95
+ @rows.each_index &block
96
+ end
97
+
98
+ def column *args, &getter
99
+ @columns << Column.new( *args, &getter )
100
+ end
101
+
102
+ alias_method :col, :column
103
+
104
+
105
+ def rows entries = nil
106
+ unless entries.nil?
107
+ @rows = entries.to_a
108
+ end
109
+
110
+ @rows
111
+ end
112
+
113
+
114
+ def to_a header: true, col_desc_refs: true
115
+ [].tap do |array|
116
+
117
+ if header
118
+ desc_ref_index = 0
119
+ array << @columns.map { |column|
120
+ if column.desc && col_desc_refs
121
+ desc_ref_index += 1
122
+ "#{ column.name }#{ SUPERSCRIPT_NUMBERS[desc_ref_index] }"
123
+ else
124
+ column.name
125
+ end
126
+ }
127
+ end
128
+
129
+ @rows.each do |row|
130
+ values = if NRSER.array_like? row
131
+ row.to_a
132
+ else
133
+ @columns.map do |column|
134
+ column.getter.call( row )
135
+ end
136
+ end
137
+
138
+ array << values.map { |value|
139
+ if value.nil?
140
+ NULL
141
+ else
142
+ value.to_s
143
+ end
144
+ }
145
+ end
146
+
147
+ end
148
+ end # #to_a
149
+
150
+ def footer
151
+ NULL + " Null\n" +
152
+ @columns.select { |col| col.desc }.each_with_index.map { |col, index|
153
+ "#{ SUPERSCRIPT_NUMBERS[index + 1] } #{ col.desc }"
154
+ }.join( "\n" )
155
+ end
156
+
157
+ end # class Locd::CLI::Table