locd 0.1.12 → 0.1.13

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/NAME +1 -0
  4. data/VERSION +1 -1
  5. data/config/default.lit.yaml +43 -0
  6. data/lib/locd.rb +0 -3
  7. data/lib/locd/agent.rb +50 -13
  8. data/lib/locd/agent/proxy.rb +27 -12
  9. data/lib/locd/agent/rotate_logs.rb +2 -2
  10. data/lib/locd/agent/site.rb +4 -1
  11. data/lib/locd/agent/system.rb +47 -12
  12. data/lib/locd/cli/command/agent.rb +48 -404
  13. data/lib/locd/cli/command/agent/add.rb +12 -4
  14. data/lib/locd/cli/command/agent/ls.rb +56 -0
  15. data/lib/locd/cli/command/agent/open.rb +53 -0
  16. data/lib/locd/cli/command/agent/plist.rb +43 -0
  17. data/lib/locd/cli/command/agent/restart.rb +43 -0
  18. data/lib/locd/cli/command/agent/rm.rb +46 -0
  19. data/lib/locd/cli/command/agent/shared.rb +253 -0
  20. data/lib/locd/cli/command/agent/start.rb +38 -0
  21. data/lib/locd/cli/command/agent/status.rb +41 -0
  22. data/lib/locd/cli/command/agent/stop.rb +39 -0
  23. data/lib/locd/cli/command/agent/tail.rb +82 -0
  24. data/lib/locd/cli/command/agent/truncate_logs.rb +65 -0
  25. data/lib/locd/cli/command/agent/update.rb +48 -0
  26. data/lib/locd/cli/command/base.rb +35 -3
  27. data/lib/locd/cli/command/job.rb +29 -36
  28. data/lib/locd/cli/command/job/add.rb +57 -0
  29. data/lib/locd/cli/command/main.rb +3 -3
  30. data/lib/locd/cli/command/proxy.rb +44 -20
  31. data/lib/locd/cli/command/rotate_logs.rb +28 -49
  32. data/lib/locd/cli/command/rotate_logs/add.rb +44 -0
  33. data/lib/locd/config.rb +88 -20
  34. data/lib/locd/config/types.rb +56 -27
  35. data/lib/locd/newsyslog.rb +23 -24
  36. data/lib/locd/proxy.rb +21 -9
  37. data/lib/locd/version.rb +94 -5
  38. data/locd.gemspec +10 -4
  39. metadata +67 -9
@@ -0,0 +1,38 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc "start", "Start an agent"
22
+
23
+ include_shared t[ groups: t.HasAny( :pattern, :multi, :start ) ]
24
+
25
+ def start
26
+ find_multi!( pattern ).
27
+ each { |agent| agent.start **option_kwds( groups: :start ) }
28
+ end
29
+
30
+ end
31
+
32
+
33
+ # /Namespace
34
+ # =======================================================================
35
+
36
+ end # module Command
37
+ end # module CLI
38
+ end # module Locd
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc 'status',
22
+ "Print agent status"
23
+
24
+ include_shared t[ groups: :pattern ]
25
+
26
+ def status
27
+ agent = find_only! pattern
28
+ respond \
29
+ label: agent.label,
30
+ status: agent.status.to_h( compact: false )
31
+ end
32
+
33
+ end
34
+
35
+
36
+ # /Namespace
37
+ # =======================================================================
38
+
39
+ end # module Command
40
+ end # module CLI
41
+ end # module Locd
@@ -0,0 +1,39 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc "stop",
22
+ "Stop an agent"
23
+
24
+ include_shared t[ groups: t.HasAny( :pattern, :multi, :stop ) ]
25
+
26
+ def stop
27
+ kwds = option_kwds groups: :stop
28
+ find_multi!( pattern ).each { |agent| agent.stop **kwds }
29
+ end
30
+
31
+ end
32
+
33
+
34
+ # /Namespace
35
+ # =======================================================================
36
+
37
+ end # module Command
38
+ end # module CLI
39
+ end # module Locd
@@ -0,0 +1,82 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc 'tail [OPTIONS] PATTERN [-- TAIL_OPTIONS]',
22
+ "Tail agent logs"
23
+
24
+ include_shared t[ groups: :pattern ]
25
+
26
+ option :stream,
27
+ desc: "Stream to tail. May omit if uses single log file.",
28
+ aliases: ['-s'],
29
+ type: :string,
30
+ enum: ['out', 'err']
31
+
32
+ option :follow,
33
+ desc: "Run with `tail -F`",
34
+ aliases: [ 'f', 'F' ],
35
+ type: :boolean
36
+
37
+ def tail *tail_options
38
+ agent = find_only! pattern
39
+
40
+ path = case options[:stream]
41
+ when nil
42
+ paths = agent.log_paths
43
+
44
+ unless paths.length == 1
45
+ raise Thor::RequiredArgumentMissingError.new binding.erb <<~END
46
+ Agent `<%= agent.label %>` has multiple log files.
47
+
48
+ out: <%= agent.out_path.to_s %>
49
+ err: <%= agent.err_path.to_s %>
50
+
51
+ Must specify one via the `--stream` option.
52
+
53
+ END
54
+ end
55
+
56
+ paths[0]
57
+
58
+ when 'out'
59
+ agent.out_path
60
+
61
+ when 'err'
62
+ agent.err_path
63
+
64
+ else
65
+ raise "WTF"
66
+ end
67
+
68
+ cmd = ['tail']
69
+ cmd += ['-F'] if options[:follow]
70
+
71
+ exec *cmd, *tail_options, path.to_s
72
+ end # #tail
73
+
74
+ end
75
+
76
+
77
+ # /Namespace
78
+ # =======================================================================
79
+
80
+ end # module Command
81
+ end # module CLI
82
+ end # module Locd
@@ -0,0 +1,65 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc 'truncate-logs',
22
+ "Truncate agent log file(s)."
23
+
24
+ include_shared t[ groups: t.has_any( :pattern, :multi ) ]
25
+
26
+ option :restart,
27
+ desc: "Restart the agent after truncation",
28
+ type: :boolean,
29
+ default: true
30
+
31
+ def truncate_logs
32
+ find_multi!( pattern ).each do |agent|
33
+ log_paths = [agent.out_path, agent.err_path].compact.uniq
34
+
35
+ unless log_paths.empty?
36
+ restart = options[:restart] && agent.running?
37
+
38
+ agent.stop if restart
39
+
40
+ log_paths.each do |log_path|
41
+ begin
42
+ log_path.open( 'w' ) { |f| f.truncate 0 }
43
+ rescue Exception => error
44
+ logger.error "Failed to truncate #{ log_path }", error
45
+ else
46
+ logger.info "Truncated",
47
+ 'file' => log_path.to_s,
48
+ 'agent.label' => agent.label
49
+ end
50
+ end # each log_path
51
+
52
+ agent.start if restart
53
+ end # unless log_paths.empty?
54
+ end # each agent
55
+ end # #truncate_logs
56
+
57
+ end
58
+
59
+
60
+ # /Namespace
61
+ # =======================================================================
62
+
63
+ end # module Command
64
+ end # module CLI
65
+ end # module Locd
@@ -0,0 +1,48 @@
1
+ # encoding: UTF-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'nrser/refinements/types'
5
+ using NRSER::Types
6
+
7
+
8
+ # Namespace
9
+ # =======================================================================
10
+
11
+ module Locd
12
+ module CLI
13
+ module Command
14
+
15
+
16
+ # Definitions
17
+ # =======================================================================
18
+
19
+ class Agent < Base
20
+
21
+ desc "update PATTERN [OPTIONS] [-- CMD_TEMPLATE...]",
22
+ "Update an existing agent"
23
+
24
+ include_shared t[ groups:
25
+ t.has_any( :write,
26
+ :add,
27
+ :respond_with_agents ) ]
28
+
29
+ def update *cmd_template
30
+ agent = find_only! pattern
31
+
32
+ new_agent = agent.update \
33
+ cmd_template: cmd_template,
34
+ **option_kwds( groups: :write )
35
+
36
+ logger.info "Agent `#{ agent.label }` updated"
37
+
38
+ respond agent
39
+ end
40
+
41
+ end
42
+
43
+ # /Namespace
44
+ # =======================================================================
45
+
46
+ end # module Command
47
+ end # module CLI
48
+ end # module Locd
@@ -11,6 +11,7 @@ require 'shellwords'
11
11
  # -----------------------------------------------------------------------
12
12
  require 'thor'
13
13
  require 'nrser/labs/i8'
14
+ require 'rouge'
14
15
 
15
16
  # Project / Package
16
17
  # -----------------------------------------------------------------------
@@ -155,11 +156,27 @@ class Base < Thor
155
156
  end
156
157
  end
157
158
  end # #render_text
159
+
160
+
161
+ def render_color?
162
+ if options.key? :color
163
+ options[:color]
164
+ else
165
+ $stdout.isatty
166
+ end
167
+ end
168
+
169
+
170
+ def render_color src, lexer_name
171
+ formatter = Rouge::Formatters::Terminal256.new
172
+ lexer = Rouge::Lexers.const_get( lexer_name ).new
173
+ formatter.format( lexer.lex( src ) )
174
+ end
158
175
 
159
176
 
160
177
  def respond message, title: nil
161
178
  formatted = if options[:json]
162
- begin
179
+ json = begin
163
180
  JSON.pretty_generate message
164
181
  rescue JSON::GeneratorError => error
165
182
  logger.debug "Error generating 'pretty' JSON, falling back to dump",
@@ -167,10 +184,25 @@ class Base < Thor
167
184
 
168
185
  JSON.dump message
169
186
  end
187
+
188
+ if render_color?
189
+ render_color json, :JSON
190
+ else
191
+ json
192
+ end
170
193
 
171
194
  elsif options[:yaml] || NRSER.hash_like?( message )
172
195
  # TODO This sucks, but it's the easiest way to get "nice" YAML :/
173
- YAML.dump JSON.load( JSON.dump message )
196
+ yaml = YAML.dump JSON.load( JSON.dump message )
197
+
198
+ if render_color?
199
+ # formatter = Rouge::Formatters::Terminal256.new
200
+ # lexer = Rouge::Lexers::YAML.new
201
+ # formatter.format( lexer.lex( yaml ) )
202
+ render_color yaml, :YAML
203
+ else
204
+ yaml
205
+ end
174
206
 
175
207
  else
176
208
  render_text message
@@ -202,7 +234,7 @@ class Base < Thor
202
234
  if error.count == 0
203
235
  logger.error "No results"
204
236
  else
205
- logger.error "Too many results:\n\n#{ render_text error.subject }\n"
237
+ logger.error "Too many results:\n\n#{ render_text error.value }\n"
206
238
  end
207
239
 
208
240
  # If the command supports `--all`, let them know that they can use it
@@ -2,6 +2,14 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
 
5
+ # Requirements
6
+ # ============================================================================
7
+
8
+ ### Project / Package ###
9
+
10
+ require_relative './agent'
11
+
12
+
5
13
  # Refinements
6
14
  # =======================================================================
7
15
 
@@ -9,12 +17,19 @@ require 'nrser/refinements/types'
9
17
  using NRSER::Types
10
18
 
11
19
 
20
+ # Namespace
21
+ # =======================================================================
22
+
23
+ module Locd
24
+ module CLI
25
+ module Command
26
+
12
27
  # Definitions
13
28
  # =======================================================================
14
29
 
15
30
  # TODO Doc me pls
16
31
  #
17
- class Locd::CLI::Command::Job < Locd::CLI::Command::Agent
32
+ class Job < Agent
18
33
 
19
34
  # Helpers
20
35
  # ============================================================================
@@ -80,39 +95,17 @@ class Locd::CLI::Command::Job < Locd::CLI::Command::Agent
80
95
  public
81
96
 
82
97
 
83
- # Write Commands
84
- # ----------------------------------------------------------------------------
85
-
86
- desc "add [OPTIONS] -- CMD_TEMPLATE...",
87
- "Add job that runs in the current directory"
88
- include_options groups: [:write, :add, :respond_with_agents]
89
- option :every,
90
- desc: "How often to start the job",
91
- type: :string
92
- option :at,
93
- desc: "Day/time to start the job",
94
- type: :hash
95
- def add *cmd_template, **kwds
96
- logger.trace "#{ self.class.name }##{ __method__ }",
97
- options: options,
98
- cmd_template: cmd_template,
99
- kwds: kwds,
100
- shared: self.class.shared_method_options
101
-
102
- kwds[:start_interval] ||= get_start_interval
103
-
104
- super *cmd_template, **kwds
105
-
106
- # job = agent_class.add \
107
- # cmd_template: cmd_template,
108
- # start_interval: get_start_interval,
109
- # **option_kwds( groups: [:write, :add] )
110
- #
111
- # logger.info "`#{ job.label }` job added."
112
- #
113
- # job.reload if options[:load]
114
- #
115
- # respond job
116
- end
98
+ # Commands
99
+ # ============================================================================
100
+
101
+ require_relative './job/add'
117
102
 
118
- end # class Locd::CLI::Command::Job
103
+ end # class Job
104
+
105
+
106
+ # /Namespace
107
+ # =======================================================================
108
+
109
+ end # module Command
110
+ end # module CLI
111
+ end # module Locd