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.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/NAME +1 -0
- data/VERSION +1 -1
- data/config/default.lit.yaml +43 -0
- data/lib/locd.rb +0 -3
- data/lib/locd/agent.rb +50 -13
- data/lib/locd/agent/proxy.rb +27 -12
- data/lib/locd/agent/rotate_logs.rb +2 -2
- data/lib/locd/agent/site.rb +4 -1
- data/lib/locd/agent/system.rb +47 -12
- data/lib/locd/cli/command/agent.rb +48 -404
- data/lib/locd/cli/command/agent/add.rb +12 -4
- data/lib/locd/cli/command/agent/ls.rb +56 -0
- data/lib/locd/cli/command/agent/open.rb +53 -0
- data/lib/locd/cli/command/agent/plist.rb +43 -0
- data/lib/locd/cli/command/agent/restart.rb +43 -0
- data/lib/locd/cli/command/agent/rm.rb +46 -0
- data/lib/locd/cli/command/agent/shared.rb +253 -0
- data/lib/locd/cli/command/agent/start.rb +38 -0
- data/lib/locd/cli/command/agent/status.rb +41 -0
- data/lib/locd/cli/command/agent/stop.rb +39 -0
- data/lib/locd/cli/command/agent/tail.rb +82 -0
- data/lib/locd/cli/command/agent/truncate_logs.rb +65 -0
- data/lib/locd/cli/command/agent/update.rb +48 -0
- data/lib/locd/cli/command/base.rb +35 -3
- data/lib/locd/cli/command/job.rb +29 -36
- data/lib/locd/cli/command/job/add.rb +57 -0
- data/lib/locd/cli/command/main.rb +3 -3
- data/lib/locd/cli/command/proxy.rb +44 -20
- data/lib/locd/cli/command/rotate_logs.rb +28 -49
- data/lib/locd/cli/command/rotate_logs/add.rb +44 -0
- data/lib/locd/config.rb +88 -20
- data/lib/locd/config/types.rb +56 -27
- data/lib/locd/newsyslog.rb +23 -24
- data/lib/locd/proxy.rb +21 -9
- data/lib/locd/version.rb +94 -5
- data/locd.gemspec +10 -4
- metadata +67 -9
data/lib/locd/config/types.rb
CHANGED
@@ -60,20 +60,28 @@ module Types
|
|
60
60
|
def self.by_key
|
61
61
|
# Got sick of writing "Hamster::Hash[...]"... "I8" <=> "Immutable"
|
62
62
|
@by_key ||= I8[
|
63
|
-
'home' =>
|
64
|
-
'bin' => ( t.
|
63
|
+
'home' => self.ConfigPath,
|
64
|
+
'bin' => ( t.When( 'locd' ) | self.ConfigPath ),
|
65
|
+
|
66
|
+
'log' => I8[
|
67
|
+
'dir' => self.ConfigPath,
|
68
|
+
],
|
69
|
+
|
70
|
+
'tmp' => I8[
|
71
|
+
'dir' => self.ConfigPath,
|
72
|
+
],
|
65
73
|
|
66
74
|
'cli' => I8[
|
67
75
|
'log' => I8[
|
68
76
|
'application' => t.non_empty_str,
|
69
77
|
'level' => NRSER::Log::Types.level?,
|
70
|
-
'dest' => ( NRSER::Log::Types.stdio |
|
78
|
+
'dest' => ( NRSER::Log::Types.stdio | self.ConfigPath ),
|
71
79
|
],
|
72
80
|
|
73
81
|
'bash_comp' => I8[
|
74
82
|
'log' => I8[
|
75
83
|
'level' => NRSER::Log::Types.level,
|
76
|
-
'dest' =>
|
84
|
+
'dest' => self.ConfigPath,
|
77
85
|
],
|
78
86
|
]
|
79
87
|
]
|
@@ -94,20 +102,23 @@ module Types
|
|
94
102
|
|
95
103
|
# @!group Type Factory Class Methods
|
96
104
|
# --------------------------------------------------------------------------
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
105
|
+
|
106
|
+
#@!method self.PackagePath **options
|
107
|
+
# @todo Document PackagePath type factory.
|
108
|
+
#
|
109
|
+
# @param [Hash] options
|
110
|
+
# Passed to {Type#initialize}.
|
111
|
+
#
|
112
|
+
# @return [Type]
|
113
|
+
#
|
114
|
+
def_type :PackagePath,
|
115
|
+
from_s: ->( s ) {
|
116
|
+
Locd::ROOT.join( s[2..-1] ) if s.start_with? '//'
|
117
|
+
},
|
118
|
+
&->( **options ) do
|
119
|
+
t.Intersection \
|
120
|
+
t.Path,
|
121
|
+
t.Where { |path|
|
111
122
|
begin
|
112
123
|
false == path.
|
113
124
|
to_pn.
|
@@ -116,17 +127,35 @@ module Types
|
|
116
127
|
rescue StandardError => error
|
117
128
|
false
|
118
129
|
end
|
119
|
-
}
|
120
|
-
|
121
|
-
|
130
|
+
},
|
131
|
+
**options
|
132
|
+
end # .PackagePath
|
122
133
|
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
134
|
+
|
135
|
+
#@!method self.ConfigPath **options
|
136
|
+
# A path we accept in the config. One of:
|
137
|
+
#
|
138
|
+
# 1. A {.PackagePath} that starts with `//...`, denoting it's relative to
|
139
|
+
# the package root.
|
140
|
+
#
|
141
|
+
# 2. A {NRSER::Types.HomePath} that starts with `~`, meaning it's relative
|
142
|
+
# to a user's home directory.
|
143
|
+
#
|
144
|
+
# 3. An {NRSER::Types.AbsPath}
|
145
|
+
#
|
146
|
+
# @param [Hash] options
|
147
|
+
# Passed to {Type#initialize}.
|
148
|
+
#
|
149
|
+
# @return [Type]
|
150
|
+
#
|
151
|
+
def_type :ConfigPath,
|
152
|
+
&->( **options ) do
|
153
|
+
t.Union \
|
154
|
+
self.PackagePath,
|
155
|
+
t.HomePath,
|
156
|
+
t.AbsPath,
|
128
157
|
**options
|
129
|
-
end #
|
158
|
+
end # .ConfigPath
|
130
159
|
|
131
160
|
# @!endgroup Type Factory Class Methods # **********************************
|
132
161
|
|
data/lib/locd/newsyslog.rb
CHANGED
@@ -32,13 +32,6 @@ module Locd::Newsyslog
|
|
32
32
|
include NRSER::Log::Mixin
|
33
33
|
|
34
34
|
|
35
|
-
# Default place to work out of.
|
36
|
-
#
|
37
|
-
# @return [Pathname]
|
38
|
-
#
|
39
|
-
DEFAULT_WORKDIR = Pathname.new( '~/.locd/tmp/newsyslog' ).expand_path
|
40
|
-
|
41
|
-
|
42
35
|
# Lil' class that holds values for a `newsyslog` conf file entry.
|
43
36
|
#
|
44
37
|
# @see https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man5/newsyslog.conf.5.html
|
@@ -74,8 +67,7 @@ module Locd::Newsyslog
|
|
74
67
|
# @param [type] arg_name
|
75
68
|
# @todo Add name param description.
|
76
69
|
#
|
77
|
-
# @return [
|
78
|
-
# @todo Document return value.
|
70
|
+
# @return [String]
|
79
71
|
#
|
80
72
|
def self.mode_string_for mode
|
81
73
|
# t.match mode,
|
@@ -91,7 +83,7 @@ module Locd::Newsyslog
|
|
91
83
|
raise ArgumentError,
|
92
84
|
"Bad mode: #{ mode.inspect }, need String or Fixnum: '644'; 0644"
|
93
85
|
end
|
94
|
-
end # .
|
86
|
+
end # .mode_string_for
|
95
87
|
|
96
88
|
|
97
89
|
def self.sig_num_for signal
|
@@ -201,7 +193,7 @@ module Locd::Newsyslog
|
|
201
193
|
# @param [Locd::Agent] agent:
|
202
194
|
# Agent to run for.
|
203
195
|
#
|
204
|
-
# @param [Pathname | String]
|
196
|
+
# @param [Pathname | String] tmp_conf_dir:
|
205
197
|
# Directory to write working files to, which are removed after successful
|
206
198
|
# runs.
|
207
199
|
#
|
@@ -212,13 +204,15 @@ module Locd::Newsyslog
|
|
212
204
|
# If we didn't run the command 'cause the agent doesn't have any logs
|
213
205
|
# (that we know/care about).
|
214
206
|
#
|
215
|
-
def self.run
|
207
|
+
def self.run agent,
|
208
|
+
tmp_conf_dir: self.tmp_conf_dir,
|
209
|
+
keep_conf_files: false
|
216
210
|
logger.debug "Calling {.run_for} agent #{ agent.label }...",
|
217
211
|
agent: agent,
|
218
|
-
|
212
|
+
tmp_conf_dir: tmp_conf_dir
|
219
213
|
|
220
|
-
# Make sure `
|
221
|
-
|
214
|
+
# Make sure `tmp_conf_dir` is a {Pathname}
|
215
|
+
tmp_conf_dir = tmp_conf_dir.to_pn
|
222
216
|
|
223
217
|
# Collect the unique log paths
|
224
218
|
log_paths = agent.log_paths
|
@@ -237,7 +231,7 @@ module Locd::Newsyslog
|
|
237
231
|
if pid = agent.pid( refresh: true )
|
238
232
|
logger.debug "Agent is running", pid: pid
|
239
233
|
|
240
|
-
pid_path =
|
234
|
+
pid_path = tmp_conf_dir / 'pids' / "#{ agent.label }.pid"
|
241
235
|
FileUtils.mkdir_p( pid_path.dirname ) unless pid_path.dirname.exist?
|
242
236
|
pid_path.write pid
|
243
237
|
|
@@ -253,13 +247,13 @@ module Locd::Newsyslog
|
|
253
247
|
entries.map { |entry|
|
254
248
|
[
|
255
249
|
entry.log_path.to_s,
|
256
|
-
entry.instance_variables.
|
250
|
+
entry.instance_variables.map { |name|
|
257
251
|
entry.instance_variable_get name
|
258
252
|
}
|
259
253
|
]
|
260
254
|
}.to_h
|
261
255
|
|
262
|
-
conf_path =
|
256
|
+
conf_path = tmp_conf_dir / 'confs' / "#{ agent.label }.conf"
|
263
257
|
FileUtils.mkdir_p( conf_path.dirname ) unless conf_path.dirname.exist?
|
264
258
|
conf_path.write conf_contents
|
265
259
|
|
@@ -290,7 +284,7 @@ module Locd::Newsyslog
|
|
290
284
|
", output:\n" + result.out.indent(1, indent_string: '> ') )
|
291
285
|
|
292
286
|
FileUtils.rm( pid_path ) if pid_path
|
293
|
-
FileUtils.rm conf_path
|
287
|
+
FileUtils.rm( conf_path ) unless keep_conf_files
|
294
288
|
|
295
289
|
logger.debug "Files cleaned up."
|
296
290
|
|
@@ -308,19 +302,19 @@ module Locd::Newsyslog
|
|
308
302
|
|
309
303
|
# Call {.run} for each agent.
|
310
304
|
#
|
311
|
-
# @param
|
305
|
+
# @param tmp_conf_dir: (see .run)
|
312
306
|
#
|
313
307
|
# @return [Hash<Locd::Agent, Cmds::Result?>]
|
314
308
|
# Hash mapping each agent to it's {.run} result (which may be `nil`).
|
315
309
|
#
|
316
|
-
def self.run_all
|
310
|
+
def self.run_all tmp_conf_dir: self.tmp_conf_dir, trim_logs: true
|
317
311
|
log_to_file do
|
318
312
|
Locd::Agent.all.values.
|
319
313
|
reject { |agent|
|
320
|
-
agent.label == Locd::
|
314
|
+
agent.label == Locd::Agent::RotateLogs.label
|
321
315
|
}.
|
322
316
|
map { |agent|
|
323
|
-
[agent, run( agent,
|
317
|
+
[agent, run( agent, tmp_conf_dir: tmp_conf_dir )]
|
324
318
|
}.
|
325
319
|
to_h.
|
326
320
|
tap { |_|
|
@@ -331,7 +325,12 @@ module Locd::Newsyslog
|
|
331
325
|
|
332
326
|
|
333
327
|
def self.log_dir
|
334
|
-
@log_dir ||= Locd.config.log_dir
|
328
|
+
@log_dir ||= Locd.config.log_dir.join( Locd::Agent::RotateLogs.label )
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
def self.tmp_conf_dir
|
333
|
+
@tmp_conf_dir ||= Locd.config.tmp_dir.join( Locd::Agent::RotateLogs.label )
|
335
334
|
end
|
336
335
|
|
337
336
|
|
data/lib/locd/proxy.rb
CHANGED
@@ -2,6 +2,19 @@
|
|
2
2
|
# encoding: UTF-8
|
3
3
|
|
4
4
|
|
5
|
+
# Refinements
|
6
|
+
# =======================================================================
|
7
|
+
|
8
|
+
require 'nrser/refinements/types'
|
9
|
+
using NRSER::Types
|
10
|
+
|
11
|
+
|
12
|
+
# Namespace
|
13
|
+
# ============================================================================
|
14
|
+
|
15
|
+
module Locd
|
16
|
+
|
17
|
+
|
5
18
|
# Definitions
|
6
19
|
# =======================================================================
|
7
20
|
|
@@ -15,7 +28,7 @@
|
|
15
28
|
# [proxymachine]: https://rubygems.org/gems/proxymachine
|
16
29
|
# [eventmachine]: https://rubygems.org/gems/eventmachine
|
17
30
|
#
|
18
|
-
module
|
31
|
+
module Proxy
|
19
32
|
|
20
33
|
# Constants
|
21
34
|
# ======================================================================
|
@@ -27,13 +40,6 @@ module Locd::Proxy
|
|
27
40
|
HOST_RE = /^Host\:\ /i
|
28
41
|
|
29
42
|
|
30
|
-
# Label for the Loc'd proxy agent itself
|
31
|
-
#
|
32
|
-
# @return [String]
|
33
|
-
#
|
34
|
-
ROTATE_LOGS_LABEL = 'com.nrser.locd.rotate-logs'
|
35
|
-
|
36
|
-
|
37
43
|
# Mixins
|
38
44
|
# ============================================================================
|
39
45
|
|
@@ -264,4 +270,10 @@ module Locd::Proxy
|
|
264
270
|
ProxyMachine.run 'locd', bind, port
|
265
271
|
end # .serve
|
266
272
|
|
267
|
-
end # module
|
273
|
+
end # module Proxy
|
274
|
+
|
275
|
+
|
276
|
+
# /Namespace
|
277
|
+
# ============================================================================
|
278
|
+
|
279
|
+
end # module Locd
|
data/lib/locd/version.rb
CHANGED
@@ -1,7 +1,44 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
##############################################################################
|
5
|
+
# This file is kind-of special: you should be able to load it totally
|
6
|
+
# independently.
|
7
|
+
#
|
8
|
+
# This means you can go
|
9
|
+
#
|
10
|
+
# load 'path/to/gem/lib/locd/version.rb'
|
11
|
+
#
|
12
|
+
# and it will succeed, regardless of paths or gems or any other environment or
|
13
|
+
# state.
|
14
|
+
#
|
15
|
+
# It defines a few very basic pieces of information about the app, and it turns
|
16
|
+
# out to be incredibly useful on an adminstration level to be able to fire up
|
17
|
+
# any old Ruby interpreter and pull that info in without worrying about all
|
18
|
+
# the other shit you need to actually run it.
|
19
|
+
#
|
20
|
+
# In general, that means that this file shouldn't require anything, and
|
21
|
+
# anything it does require must not depend on anything outside Ruby's standard
|
22
|
+
# library.
|
23
|
+
#
|
24
|
+
# This file is loaded by `//locd.gemspec` to get the version information,
|
25
|
+
# which is in turn loaded from the `//VERSION` file (see {Locd::VERSION}).
|
26
|
+
#
|
27
|
+
##############################################################################
|
28
|
+
|
29
|
+
|
30
|
+
# Requirements
|
31
|
+
# ========================================================================
|
32
|
+
|
33
|
+
# Stdlib
|
34
|
+
# ------------------------------------------------------------------------
|
35
|
+
|
4
36
|
require 'pathname'
|
37
|
+
require 'singleton'
|
38
|
+
|
39
|
+
|
40
|
+
# Definitions
|
41
|
+
# ========================================================================
|
5
42
|
|
6
43
|
module Locd
|
7
44
|
# Absolute, expanded path to the gem's root directory.
|
@@ -11,16 +48,68 @@ module Locd
|
|
11
48
|
ROOT = Pathname.new( __dir__ ).join( '..', '..' ).expand_path
|
12
49
|
|
13
50
|
|
14
|
-
# String version read from `//VERSION`
|
51
|
+
# String version read from `//VERSION` and used in the gemspec.
|
52
|
+
#
|
53
|
+
# I use this approach in order to create a standard versioning system across
|
54
|
+
# *any* package, regardless or runtime, and so that tools can figure out
|
55
|
+
# what version a package is without even having it's runtime available.
|
56
|
+
#
|
57
|
+
# This has turned out to be super helpful, and I'm surprised it isn't more
|
58
|
+
# common or standardized in some way... I think pretty much every package
|
59
|
+
# in very language has a root directory and is capable of reading a file
|
60
|
+
# to figure out it's state.
|
15
61
|
#
|
16
62
|
# @return [String]
|
17
63
|
#
|
18
|
-
VERSION = (ROOT
|
64
|
+
VERSION = (ROOT + 'VERSION').read.chomp
|
19
65
|
|
20
66
|
|
21
|
-
# The gem name
|
67
|
+
# The gem name, read from the `//NAME` file, and used in the gemspec.
|
68
|
+
#
|
69
|
+
# See {Locd::VERSION} for an explanation of why bare files in the package
|
70
|
+
# root are used.
|
22
71
|
#
|
23
72
|
# @return [String]
|
24
73
|
#
|
25
|
-
GEM_NAME = '
|
26
|
-
|
74
|
+
GEM_NAME = (ROOT + 'NAME').read.chomp
|
75
|
+
|
76
|
+
|
77
|
+
# {Singleton} extension of {Gem::Version} that loads {Locd::VERSION} and
|
78
|
+
# provides some convenient methods.
|
79
|
+
#
|
80
|
+
class Version < Gem::Version
|
81
|
+
include ::Singleton
|
82
|
+
|
83
|
+
# Private method to instantiate the {#instance} using the {Locd::VERSION}
|
84
|
+
# {String}.
|
85
|
+
#
|
86
|
+
# @return [Version]
|
87
|
+
#
|
88
|
+
def self.new
|
89
|
+
super Locd::VERSION
|
90
|
+
end
|
91
|
+
|
92
|
+
# We need to mark {.new} as private to dissuade construction of additional
|
93
|
+
# instances.
|
94
|
+
private_class_method :new
|
95
|
+
|
96
|
+
# Proxies to the {#instance}'s {#dev?}.
|
97
|
+
#
|
98
|
+
# @return (see #dev?)
|
99
|
+
#
|
100
|
+
def self.dev?
|
101
|
+
instance.dev?
|
102
|
+
end
|
103
|
+
|
104
|
+
# Tests if the package's version is a development pre-release.
|
105
|
+
#
|
106
|
+
# @return [Boolean]
|
107
|
+
# `true` if this is a development pre-release.
|
108
|
+
#
|
109
|
+
def dev?
|
110
|
+
segments[3] == 'dev'
|
111
|
+
end
|
112
|
+
|
113
|
+
end # module Version
|
114
|
+
|
115
|
+
end # module Locd
|
data/locd.gemspec
CHANGED
@@ -29,12 +29,16 @@ Gem::Specification.new do |spec|
|
|
29
29
|
# Development Dependencies
|
30
30
|
# ----------------------------------------------------------------------------
|
31
31
|
|
32
|
-
spec.add_development_dependency "bundler", "
|
32
|
+
spec.add_development_dependency "bundler", ">= 1.16"
|
33
33
|
spec.add_development_dependency "rake", "~> 10.0"
|
34
34
|
spec.add_development_dependency "rspec", "~> 3.7"
|
35
35
|
|
36
36
|
# Nicer REPL experience
|
37
37
|
spec.add_development_dependency "pry", '~> 0.10.4'
|
38
|
+
spec.add_development_dependency "pry-rescue", '~> 1.4.5'
|
39
|
+
spec.add_development_dependency "pry-stack_explorer", '~> 0.4.9'
|
40
|
+
|
41
|
+
|
38
42
|
# GitHub-Flavored Markdown (GFM) for use with `yard`
|
39
43
|
spec.add_development_dependency 'github-markup', '~> 1.6'
|
40
44
|
# Doc site generation with `yard`
|
@@ -47,7 +51,7 @@ Gem::Specification.new do |spec|
|
|
47
51
|
# ----------------------------------------------------------------------------
|
48
52
|
|
49
53
|
# My guns
|
50
|
-
spec.add_dependency "nrser", '~> 0.3.
|
54
|
+
spec.add_dependency "nrser", '~> 0.3.12'
|
51
55
|
|
52
56
|
# Used to process command templates from projects' `//dev/locd.yml` files
|
53
57
|
spec.add_dependency "cmds", ">= 0.2.10"
|
@@ -59,8 +63,10 @@ Gem::Specification.new do |spec|
|
|
59
63
|
spec.add_dependency 'plist', '~> 3.4'
|
60
64
|
|
61
65
|
# Atli, my fork of Thor for CLI interface
|
62
|
-
spec.add_dependency 'atli', '~> 0.1.
|
66
|
+
spec.add_dependency 'atli', '~> 0.1.13'
|
63
67
|
|
64
|
-
#
|
68
|
+
# TODO IDK what was going on here..
|
65
69
|
# spec.add_dependency 'terminal-table', '~> 1.8'
|
70
|
+
|
71
|
+
spec.add_dependency 'rouge', '~> 3.1.1'
|
66
72
|
end
|