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
@@ -0,0 +1,57 @@
|
|
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 Job < Agent
|
20
|
+
|
21
|
+
desc "add [OPTIONS] -- CMD_TEMPLATE...",
|
22
|
+
"Add job that runs in the current directory"
|
23
|
+
|
24
|
+
include_shared t[ groups:
|
25
|
+
t.has_any( :write,
|
26
|
+
:add,
|
27
|
+
:respond_with_agents ) ]
|
28
|
+
|
29
|
+
option :every,
|
30
|
+
desc: "How often to start the job",
|
31
|
+
type: :string
|
32
|
+
|
33
|
+
option :at,
|
34
|
+
desc: "Day/time to start the job",
|
35
|
+
type: :hash
|
36
|
+
|
37
|
+
def add *cmd_template, **kwds
|
38
|
+
logger.trace "#{ self.class.name }##{ __method__ }",
|
39
|
+
options: options,
|
40
|
+
cmd_template: cmd_template,
|
41
|
+
kwds: kwds,
|
42
|
+
shared: self.class.shared_method_options
|
43
|
+
|
44
|
+
kwds[:start_interval] ||= get_start_interval
|
45
|
+
|
46
|
+
super *cmd_template, **kwds
|
47
|
+
end
|
48
|
+
|
49
|
+
end # class Job
|
50
|
+
|
51
|
+
|
52
|
+
# /Namespace
|
53
|
+
# =======================================================================
|
54
|
+
|
55
|
+
end # module Command
|
56
|
+
end # module CLI
|
57
|
+
end # module Locd
|
@@ -59,6 +59,7 @@ class Main < Base
|
|
59
59
|
#
|
60
60
|
|
61
61
|
common_class_options :backtrace
|
62
|
+
common_class_options :color
|
62
63
|
|
63
64
|
class_option :log_level,
|
64
65
|
desc: "Set log level",
|
@@ -220,9 +221,8 @@ class Main < Base
|
|
220
221
|
Locd::CLI::Command::Proxy,
|
221
222
|
desc: 'Deal with the HTTP proxy that routes requests to servers'
|
222
223
|
|
223
|
-
|
224
|
-
|
225
|
-
subcommand 'rotate_logs',
|
224
|
+
|
225
|
+
subcommand 'rotate-logs',
|
226
226
|
Locd::CLI::Command::RotateLogs,
|
227
227
|
desc: 'Deal with the log rotation job'
|
228
228
|
|
@@ -1,18 +1,21 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
4
|
+
|
3
5
|
# Requirements
|
4
6
|
# =======================================================================
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
+
### Stdlib ###
|
9
|
+
|
8
10
|
require 'shellwords'
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
+
### Deps ###
|
13
|
+
|
12
14
|
require 'thor'
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
+
### Project / Package ###
|
17
|
+
|
18
|
+
require_relative './agent'
|
16
19
|
|
17
20
|
|
18
21
|
# Refinements
|
@@ -22,6 +25,14 @@ require 'nrser/refinements/types'
|
|
22
25
|
using NRSER::Types
|
23
26
|
|
24
27
|
|
28
|
+
# Namespace
|
29
|
+
# =======================================================================
|
30
|
+
|
31
|
+
module Locd
|
32
|
+
module CLI
|
33
|
+
module Command
|
34
|
+
|
35
|
+
|
25
36
|
# Definitions
|
26
37
|
# =======================================================================
|
27
38
|
|
@@ -29,7 +40,7 @@ using NRSER::Types
|
|
29
40
|
#
|
30
41
|
# @see http://whatisthor.com/
|
31
42
|
#
|
32
|
-
class
|
43
|
+
class Proxy < Agent
|
33
44
|
|
34
45
|
|
35
46
|
# Helpers
|
@@ -52,7 +63,7 @@ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
|
|
52
63
|
logger.error "Proxy agent plist not found",
|
53
64
|
expected_path: Locd::Agent::Proxy.plist_abs_path.to_s
|
54
65
|
|
55
|
-
logger.info "Run `locd
|
66
|
+
logger.info "Run `locd proxy add` to create it."
|
56
67
|
|
57
68
|
exit 1
|
58
69
|
end
|
@@ -65,19 +76,23 @@ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
|
|
65
76
|
public
|
66
77
|
|
67
78
|
|
68
|
-
|
69
79
|
# Commands
|
70
80
|
# ============================================================================
|
71
81
|
|
72
82
|
desc "add",
|
73
83
|
"Add agents that runs a command in the current directory"
|
74
|
-
|
84
|
+
|
85
|
+
include_shared t[ groups: t.HasAny( :add,
|
86
|
+
:respond_with_agents ) ]
|
87
|
+
|
88
|
+
include_shared t[ groups: :write, name: t.Not( :label ) ]
|
89
|
+
|
75
90
|
def add
|
76
91
|
agent = agent_class.add **option_kwds( groups: :write )
|
77
92
|
|
78
93
|
logger.info "`#{ agent.label }` agent created."
|
79
94
|
|
80
|
-
agent.
|
95
|
+
agent.reload if options[:load]
|
81
96
|
|
82
97
|
respond agent
|
83
98
|
end
|
@@ -85,11 +100,13 @@ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
|
|
85
100
|
|
86
101
|
desc "run",
|
87
102
|
"Run the proxy server (in the foreground)"
|
103
|
+
|
88
104
|
method_option :bind,
|
89
105
|
desc: "Address to bind the proxy server to",
|
90
106
|
aliases: ['-b', '--host', '-h'],
|
91
107
|
type: :string,
|
92
108
|
default: Locd.config[:proxy, :bind]
|
109
|
+
|
93
110
|
method_option :port,
|
94
111
|
desc: "Port to run the proxy on",
|
95
112
|
aliases: '-p',
|
@@ -104,6 +121,7 @@ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
|
|
104
121
|
|
105
122
|
desc "port",
|
106
123
|
"Get port Loc'd proxy is running on or configured for"
|
124
|
+
|
107
125
|
def port
|
108
126
|
respond Locd::Proxy.port
|
109
127
|
end
|
@@ -145,33 +163,39 @@ class Locd::CLI::Command::Proxy < Locd::CLI::Command::Agent
|
|
145
163
|
|
146
164
|
desc "start",
|
147
165
|
"Start the proxy"
|
148
|
-
|
149
|
-
desc: "Set `launchd` *Disabled* key to `false`",
|
150
|
-
type: :boolean
|
166
|
+
include_shared t[ groups: :start ]
|
151
167
|
def start
|
152
|
-
proxy.start **option_kwds( :
|
168
|
+
proxy.start **option_kwds( groups: :start )
|
153
169
|
end
|
154
170
|
|
155
171
|
|
156
172
|
desc "stop",
|
157
173
|
"Stop the proxy"
|
158
|
-
|
174
|
+
include_shared t[ groups: :stop ]
|
159
175
|
option :write,
|
160
176
|
desc: "Set `launchd` *Disabled* key to `true`",
|
161
177
|
type: :boolean
|
162
178
|
def stop
|
163
|
-
proxy.stop **option_kwds(
|
179
|
+
proxy.stop **option_kwds( groups: :stop )
|
164
180
|
end
|
165
181
|
|
166
182
|
|
167
183
|
desc "restart",
|
168
184
|
"Restart the proxy"
|
169
|
-
|
185
|
+
include_shared t[ groups: t.HasAny( :start, :stop ) ]
|
170
186
|
option :write,
|
171
187
|
desc: "Set `launchd` *Disabled* key to `false`",
|
172
188
|
type: :boolean
|
173
189
|
def restart
|
174
|
-
proxy.restart **option_kwds( :
|
190
|
+
proxy.restart **option_kwds( groups: [ :start, :stop ] )
|
175
191
|
end
|
176
192
|
|
177
|
-
end #
|
193
|
+
end # class Proxy
|
194
|
+
|
195
|
+
|
196
|
+
# /Namespace
|
197
|
+
# ============================================================================
|
198
|
+
|
199
|
+
end # module Command
|
200
|
+
end # module CLI
|
201
|
+
end # module Locd
|
@@ -22,12 +22,20 @@ require 'nrser/refinements/types'
|
|
22
22
|
using NRSER::Types
|
23
23
|
|
24
24
|
|
25
|
+
# Namespace
|
26
|
+
# =======================================================================
|
27
|
+
|
28
|
+
module Locd
|
29
|
+
module CLI
|
30
|
+
module Command
|
31
|
+
|
32
|
+
|
25
33
|
# Definitions
|
26
34
|
# =======================================================================
|
27
35
|
|
28
36
|
# Manage log rotation.
|
29
37
|
#
|
30
|
-
class
|
38
|
+
class RotateLogs < Job
|
31
39
|
|
32
40
|
|
33
41
|
# Helpers
|
@@ -58,7 +66,13 @@ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Job
|
|
58
66
|
agent
|
59
67
|
end
|
60
68
|
end
|
61
|
-
|
69
|
+
|
70
|
+
|
71
|
+
def find_only! pattern; agent; end
|
72
|
+
|
73
|
+
def find_multi! pattern; [ agent ]; end
|
74
|
+
|
75
|
+
|
62
76
|
# end protected
|
63
77
|
public
|
64
78
|
|
@@ -66,35 +80,7 @@ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Job
|
|
66
80
|
# Commands
|
67
81
|
# ============================================================================
|
68
82
|
|
69
|
-
|
70
|
-
"Add agents that runs a command in the current directory"
|
71
|
-
include_options groups: [:write, :add, :respond_with_agents]
|
72
|
-
def add *cmd_template, **kwds
|
73
|
-
if cmd_template.empty? || cmd_template.all?( &:empty? )
|
74
|
-
cmd_template = agent_class.default_cmd_template
|
75
|
-
end
|
76
|
-
|
77
|
-
if options.key? :label
|
78
|
-
raise Thor::ProhibitedArgumentError,
|
79
|
-
"Label can not be customized on system agents"
|
80
|
-
end
|
81
|
-
|
82
|
-
kwds[:start_interval] ||= if options[:every] || options[:at]
|
83
|
-
get_start_interval
|
84
|
-
else
|
85
|
-
agent_class.default_start_interval
|
86
|
-
end
|
87
|
-
|
88
|
-
super *cmd_template, **kwds
|
89
|
-
|
90
|
-
# agent = agent_class.add **add_kwds
|
91
|
-
#
|
92
|
-
# logger.info "`#{ agent.label }` agent created."
|
93
|
-
#
|
94
|
-
# agent.reload if options[:load]
|
95
|
-
#
|
96
|
-
# respond agent
|
97
|
-
end
|
83
|
+
require_relative './rotate_logs/add'
|
98
84
|
|
99
85
|
|
100
86
|
desc "run",
|
@@ -107,22 +93,6 @@ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Job
|
|
107
93
|
# Agent Interface
|
108
94
|
# ----------------------------------------------------------------------------
|
109
95
|
|
110
|
-
desc 'status',
|
111
|
-
'Print agent status'
|
112
|
-
def status
|
113
|
-
respond \
|
114
|
-
label: agent.label,
|
115
|
-
status: agent.status
|
116
|
-
end
|
117
|
-
|
118
|
-
|
119
|
-
desc "rm",
|
120
|
-
"Remove (uninstall, delete) the agent"
|
121
|
-
map remove: :rm
|
122
|
-
def rm
|
123
|
-
agent.remove
|
124
|
-
end
|
125
|
-
|
126
96
|
|
127
97
|
desc "plist",
|
128
98
|
"Show the agent's launchd property list"
|
@@ -147,7 +117,7 @@ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Job
|
|
147
117
|
|
148
118
|
desc "stop",
|
149
119
|
"Stop the agent"
|
150
|
-
|
120
|
+
include_shared t[ groups: :stop ]
|
151
121
|
option :write,
|
152
122
|
desc: "Set `launchd` *Disabled* key to `true`",
|
153
123
|
type: :boolean
|
@@ -158,12 +128,21 @@ class Locd::CLI::Command::RotateLogs < Locd::CLI::Command::Job
|
|
158
128
|
|
159
129
|
desc "restart",
|
160
130
|
"Restart the agent"
|
161
|
-
|
131
|
+
include_shared t[ groups: :stop ]
|
162
132
|
option :write,
|
163
133
|
desc: "Set `launchd` *Disabled* key to `false`",
|
164
134
|
type: :boolean
|
165
135
|
def restart
|
166
136
|
agent.restart **option_kwds( :write, groups: :stop )
|
167
137
|
end
|
138
|
+
|
168
139
|
|
169
140
|
end # module Locd::CLI::RotateLogs
|
141
|
+
|
142
|
+
|
143
|
+
# /Namespace
|
144
|
+
# ========================================================================
|
145
|
+
|
146
|
+
end # module Command
|
147
|
+
end # module CLI
|
148
|
+
end # module Locd
|
@@ -0,0 +1,44 @@
|
|
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 RotateLogs < Job
|
20
|
+
|
21
|
+
desc "add [OPTIONS] [-- CMD_TEMPLATE...]",
|
22
|
+
"Add the rotate-logs agent"
|
23
|
+
|
24
|
+
include_shared t[ groups: t.has_any( :add, :respond_with_agents ) ]
|
25
|
+
|
26
|
+
def add
|
27
|
+
agent = agent_class.add **option_kwds( groups: [ :write, :add ] )
|
28
|
+
|
29
|
+
logger.info "#{ agent_class.name } `#{ agent.label }` created."
|
30
|
+
|
31
|
+
agent.reload if options[:load]
|
32
|
+
|
33
|
+
respond agent
|
34
|
+
end
|
35
|
+
|
36
|
+
end # class RotateLogs
|
37
|
+
|
38
|
+
|
39
|
+
# /Namespace
|
40
|
+
# =======================================================================
|
41
|
+
|
42
|
+
end # module Command
|
43
|
+
end # module CLI
|
44
|
+
end # module Locd
|
data/lib/locd/config.rb
CHANGED
@@ -12,6 +12,8 @@ require 'pathname'
|
|
12
12
|
# -----------------------------------------------------------------------
|
13
13
|
require 'nrser'
|
14
14
|
require 'nrser/core_ext/object'
|
15
|
+
require 'nrser/labs/i8'
|
16
|
+
require 'nrser/labs/i8/struct'
|
15
17
|
|
16
18
|
|
17
19
|
# Project / Package
|
@@ -64,7 +66,21 @@ class Locd::Config
|
|
64
66
|
# @return [String]
|
65
67
|
#
|
66
68
|
KEY_SEPARATOR = '.'
|
69
|
+
|
67
70
|
|
71
|
+
# Classes
|
72
|
+
# ============================================================================
|
73
|
+
|
74
|
+
class FileLoad < I8::Struct.new(
|
75
|
+
name: t.label?,
|
76
|
+
path: t.Path,
|
77
|
+
prev: t.Hash,
|
78
|
+
parse: t.Hash,
|
79
|
+
post: t.Hash,
|
80
|
+
)
|
81
|
+
|
82
|
+
end # class FileLoad
|
83
|
+
|
68
84
|
|
69
85
|
# Attributes
|
70
86
|
# ============================================================================
|
@@ -74,6 +90,13 @@ class Locd::Config
|
|
74
90
|
# @return [Pathname]
|
75
91
|
#
|
76
92
|
attr_reader :default_config_path
|
93
|
+
|
94
|
+
|
95
|
+
# TODO document `file_loads` attribute.
|
96
|
+
#
|
97
|
+
# @return [Array<FileLoad>]
|
98
|
+
#
|
99
|
+
attr_reader :file_loads
|
77
100
|
|
78
101
|
|
79
102
|
# Constructor
|
@@ -85,16 +108,29 @@ class Locd::Config
|
|
85
108
|
@default_config_path = default_config_path.to_pn
|
86
109
|
@dev_config_path = dev_config_path.to_pn
|
87
110
|
|
111
|
+
@file_loads = []
|
88
112
|
@from_files = {}
|
89
113
|
|
90
|
-
|
114
|
+
begin
|
115
|
+
load_file! default_config_path, name: :default
|
116
|
+
rescue StandardError => error
|
117
|
+
logger.error "Failed to load default config!", error
|
118
|
+
end
|
91
119
|
|
92
|
-
|
93
|
-
|
120
|
+
begin
|
121
|
+
if user_config_path.exist?
|
122
|
+
load_file! user_config_path, name: :user
|
123
|
+
end
|
124
|
+
rescue Exception => error
|
125
|
+
logger.error "Failed to load user config!", error
|
94
126
|
end
|
95
127
|
|
96
|
-
|
97
|
-
|
128
|
+
begin
|
129
|
+
if dev_config_path && dev_config_path.exist?
|
130
|
+
load_file! dev_config_path, name: :dev
|
131
|
+
end
|
132
|
+
rescue Exception => error
|
133
|
+
logger.error "Failed to load dev config!", error
|
98
134
|
end
|
99
135
|
end # #initialize
|
100
136
|
|
@@ -113,11 +149,19 @@ class Locd::Config
|
|
113
149
|
#
|
114
150
|
# @return [nil]
|
115
151
|
#
|
116
|
-
def load_file! path
|
117
|
-
path.
|
118
|
-
|
119
|
-
|
120
|
-
|
152
|
+
def load_file! path, name: nil
|
153
|
+
parse = path.to_pn.read.thru { |str| YAML.safe_load str }
|
154
|
+
post = @from_files.deep_merge parse
|
155
|
+
|
156
|
+
@file_loads << FileLoad.new(
|
157
|
+
name: name,
|
158
|
+
path: path,
|
159
|
+
prev: @from_files,
|
160
|
+
parse: parse,
|
161
|
+
post: post,
|
162
|
+
)
|
163
|
+
|
164
|
+
@from_files = post
|
121
165
|
|
122
166
|
nil
|
123
167
|
end # #load_file!
|
@@ -164,10 +208,20 @@ class Locd::Config
|
|
164
208
|
|
165
209
|
return value if type.nil?
|
166
210
|
|
167
|
-
|
168
|
-
type.
|
169
|
-
|
170
|
-
|
211
|
+
begin
|
212
|
+
if value.is_a?( String ) && type.has_from_s?
|
213
|
+
type.from_s value
|
214
|
+
else
|
215
|
+
type.check! value
|
216
|
+
end
|
217
|
+
rescue NRSER::TypeError => error
|
218
|
+
error.context.merge! \
|
219
|
+
key: key,
|
220
|
+
value: value,
|
221
|
+
type: type,
|
222
|
+
current_config_from_files: @from_files
|
223
|
+
|
224
|
+
raise error
|
171
225
|
end
|
172
226
|
end
|
173
227
|
|
@@ -247,22 +301,36 @@ class Locd::Config
|
|
247
301
|
end
|
248
302
|
|
249
303
|
|
304
|
+
# Absolute path to Loc'd home directory (it's workspace). Doesn't check that
|
305
|
+
# the directory exists or anything.
|
306
|
+
#
|
250
307
|
# @return [Pathname]
|
251
|
-
# Absolute path to Loc'd home directory (it's workspace).
|
252
|
-
# Directory may not exist, or may be something else like a file.
|
253
308
|
#
|
254
309
|
def home_dir
|
255
|
-
self[:home
|
310
|
+
self[:home].to_pn
|
256
311
|
end
|
257
312
|
|
258
|
-
|
313
|
+
|
314
|
+
# Directory to save system logs in (proxy, newsyslog, etc...)
|
315
|
+
#
|
316
|
+
# @return [Pathname]
|
317
|
+
#
|
259
318
|
def log_dir
|
260
319
|
self[
|
261
|
-
:
|
262
|
-
|
320
|
+
:log,
|
321
|
+
:dir,
|
263
322
|
default: (home_dir / 'log')
|
264
323
|
]
|
265
324
|
end
|
325
|
+
|
326
|
+
|
327
|
+
def tmp_dir
|
328
|
+
self[
|
329
|
+
:tmp,
|
330
|
+
:dir,
|
331
|
+
default: ( home_dir / 'tmp' )
|
332
|
+
]
|
333
|
+
end
|
266
334
|
|
267
335
|
|
268
336
|
# @return [Pathname]
|