adminix 0.1.24 → 0.1.25
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/exe/adminix +1 -3
- data/lib/adminix/config.rb +69 -12
- data/lib/adminix/log_watch_handler.rb +23 -0
- data/lib/adminix/service.rb +47 -4
- data/lib/adminix/setup/routes.rb +5 -1
- data/lib/adminix/setup/services.rb +5 -4
- data/lib/adminix/version.rb +1 -1
- data/lib/adminix/watcher.rb +40 -8
- data/lib/adminix.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed51b6024e1e9da59e6f64d6ec5dc5187d59bd46
|
4
|
+
data.tar.gz: d595961de804152a6d571b761e749a0a6ef65f14
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca709fe8f560c59566a2046c59d2c0c06c35efe9192b9d94b81a51c4b09d31386688ed56b331716cef6ac4dfdf81f74c9025d7c81dd5191e4ee52711cabbdb92
|
7
|
+
data.tar.gz: fce3a9bed9d92d62e6b70e0b8f4b36e417c0a545ab7189585e58fd4d7a6d49637273c2fd71ce5fb97be5535709e3c7178fd3a2c73b069f72b2927ae3c96289bf
|
data/exe/adminix
CHANGED
@@ -48,9 +48,7 @@ unless options[:action] == "help"
|
|
48
48
|
config.secret_key = options[:secret_key]
|
49
49
|
config.service_id = options[:service_id]
|
50
50
|
config.daemon = options[:daemonize]
|
51
|
-
|
52
|
-
config.read_creds_file
|
53
|
-
end
|
51
|
+
config.read_local_config
|
54
52
|
end
|
55
53
|
|
56
54
|
case options[:action]
|
data/lib/adminix/config.rb
CHANGED
@@ -6,35 +6,92 @@ module Adminix
|
|
6
6
|
include Singleton
|
7
7
|
|
8
8
|
DEFAULT_HOST = 'https://api.adminix.io'.freeze
|
9
|
+
DEFAULT_WEBSOCKET_HOST = 'wss://api.adminix.io/websocket'.freeze
|
9
10
|
DEFAULT_SETUP_SERVER_PORT = '8080'
|
10
11
|
|
11
|
-
attr_accessor :service_id, :secret_key, :host, :commands, :daemon, :setup_server_port
|
12
|
+
attr_accessor :service_id, :secret_key, :host, :commands, :daemon, :setup_server_port, :scripts, :watch_log_files, :watcher_sync_period, :logs_sync_period, :websocket_path, :mode
|
12
13
|
|
13
14
|
def initialize
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
@host = ENV['ADMINIX_HOST'] || DEFAULT_HOST
|
16
|
+
@setup_server_port = ENV['ADMINIX_SETUP_SERVER_PORT'] || DEFAULT_SETUP_SERVER_PORT
|
17
|
+
@commands = []
|
18
|
+
@watcher_sync_period = 10
|
19
|
+
@logs_sync_period = 3
|
20
|
+
@websocket_path = ENV['ADMINIX_WEBSOCKET_HOST'] || DEFAULT_WEBSOCKET_HOST
|
21
|
+
@mode = 'classic'
|
22
|
+
@scripts = {
|
23
|
+
watcher_start: 'sudo systemctl start adminix.service',
|
24
|
+
watcher_stop: 'sudo systemctl stop adminix.service',
|
25
|
+
process_start: 'sudo systemctl start adminix_process.service',
|
26
|
+
process_stop: 'sudo systemctl stop adminix_process.service'
|
27
|
+
}
|
28
|
+
@watch_log_files = []
|
29
|
+
|
30
|
+
@config_store_path = "#{ENV['HOME']}/.config"
|
31
|
+
@root_path = "#{@config_store_path}/adminix"
|
32
|
+
@creds_path = "#{@root_path}/credentials"
|
33
|
+
@config_path = "#{@root_path}/config"
|
17
34
|
end
|
18
35
|
|
19
|
-
def read_creds_file
|
20
|
-
file_content = IO.read("#{ENV['HOME']}/.adminix")
|
21
|
-
data = JSON.parse(file_content) rescue nil
|
22
36
|
|
23
|
-
|
24
|
-
|
25
|
-
|
37
|
+
def read_local_config
|
38
|
+
if File.exists?(@creds_path)
|
39
|
+
content = IO.read(@creds_path)
|
40
|
+
data = JSON.parse(content) rescue {}
|
41
|
+
|
42
|
+
@service_id ||= data['service_id']
|
43
|
+
@secret_key ||= data['secret_key']
|
26
44
|
end
|
27
45
|
|
28
|
-
|
46
|
+
if File.exists?(@config_path)
|
47
|
+
content = IO.read(@config_path)
|
48
|
+
data = JSON.parse(content) rescue {}
|
49
|
+
|
50
|
+
@mode = data['mode'] || 'classic'
|
51
|
+
|
52
|
+
scripts = data['scripts'] || {}
|
53
|
+
@scripts = {
|
54
|
+
watcher_start: scripts['watcher_start'],
|
55
|
+
watcher_stop: scripts['watcher_stop'],
|
56
|
+
process_start: scripts['process_start'],
|
57
|
+
process_stop: scripts['process_stop']
|
58
|
+
}
|
59
|
+
|
60
|
+
@watch_log_files = data['watch_logs'] || []
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def export_credentials
|
65
|
+
create_config_root_if_not_exists
|
66
|
+
|
67
|
+
open(@creds_path, 'w') do |f|
|
68
|
+
f.puts(credentials.to_json)
|
69
|
+
end
|
29
70
|
end
|
30
71
|
|
31
72
|
def creds_file_exists?
|
32
|
-
File.exists?(
|
73
|
+
File.exists?(@creds_path)
|
33
74
|
end
|
34
75
|
|
35
76
|
def credentials_defined?
|
36
77
|
!service_id.nil? && !secret_key.nil?
|
37
78
|
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def credentials
|
83
|
+
{ service_id: @service_id, secret_key: @secret_key }
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_config_root_if_not_exists
|
87
|
+
unless Dir.exists?(@config_store_path)
|
88
|
+
Dir.mkdir(@config_store_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
unless Dir.exists?(@root_path)
|
92
|
+
Dir.mkdir(@root_path)
|
93
|
+
end
|
94
|
+
end
|
38
95
|
end
|
39
96
|
end
|
40
97
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Adminix
|
2
|
+
module LogWatchHandler
|
3
|
+
def file_modified
|
4
|
+
#puts "#{path} modified"
|
5
|
+
unless Service.instance.syncing_logs
|
6
|
+
Service.instance.new_logs = true
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def file_moved
|
11
|
+
#puts "#{path} moved"
|
12
|
+
end
|
13
|
+
|
14
|
+
def file_deleted
|
15
|
+
#puts "#{path} deleted"
|
16
|
+
end
|
17
|
+
|
18
|
+
def unbind
|
19
|
+
#puts "#{path} monitoring ceased"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/lib/adminix/service.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
require 'singleton'
|
2
2
|
require 'net/http'
|
3
|
-
|
3
|
+
require 'byebug'
|
4
4
|
module Adminix
|
5
5
|
class Service
|
6
6
|
include Singleton
|
7
7
|
|
8
|
-
|
8
|
+
attr_accessor :new_logs
|
9
|
+
attr_reader :id, :process_id, :watching_logs, :syncing_logs
|
9
10
|
|
10
11
|
def initialize
|
11
12
|
@id = config.service_id
|
13
|
+
@watching_logs = []
|
14
|
+
@new_logs = false
|
15
|
+
@syncing_logs = false
|
12
16
|
end
|
13
17
|
|
14
18
|
def to_cable
|
@@ -37,6 +41,30 @@ module Adminix
|
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
44
|
+
def sync_logs(ws_client)
|
45
|
+
return unless new_logs
|
46
|
+
|
47
|
+
@syncing_logs = true
|
48
|
+
|
49
|
+
@watching_logs.each do |l|
|
50
|
+
initial_length = l[:lines]
|
51
|
+
current_length = file_lines_number(l[:path])
|
52
|
+
new_lines = current_length > initial_length ? current_length - initial_length : 100
|
53
|
+
lines = `tail -#{new_lines} #{l[:path]}`.split("\n") rescue []
|
54
|
+
payload = lines.map { |line| { created_at: Time.now.to_s, level: 'NOTICE', message: line } }
|
55
|
+
begin
|
56
|
+
puts "Syncing new logs"
|
57
|
+
ws_client.perform(:add_logs, { logs: payload }) if ws_client.subscribed?
|
58
|
+
rescue
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
count_logs_lines
|
63
|
+
|
64
|
+
@new_logs = false
|
65
|
+
@syncing_logs = false
|
66
|
+
end
|
67
|
+
|
40
68
|
def options_to_envs
|
41
69
|
data = fetch_options
|
42
70
|
|
@@ -60,7 +88,7 @@ module Adminix
|
|
60
88
|
end
|
61
89
|
|
62
90
|
def fetch_options
|
63
|
-
uri = URI.parse("#{config.host}/
|
91
|
+
uri = URI.parse("#{config.host}/v1/services/#{id}/options")
|
64
92
|
request = Net::HTTP::Get.new(uri)
|
65
93
|
request["Authorization"] = "Bearer #{config.secret_key}"
|
66
94
|
|
@@ -72,13 +100,24 @@ module Adminix
|
|
72
100
|
JSON.parse(response.body)
|
73
101
|
end
|
74
102
|
|
103
|
+
def count_logs_lines
|
104
|
+
@watching_logs = config.watch_log_files.map do |file_path|
|
105
|
+
{ lines: file_lines_number(file_path), path: file_path }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
75
109
|
def restart!
|
76
110
|
stop!
|
77
111
|
end
|
78
112
|
|
79
113
|
def stop!
|
80
114
|
system.log "Stopping process"
|
81
|
-
|
115
|
+
case config.mode
|
116
|
+
when 'classic'
|
117
|
+
system.eval("#{config.scripts[:watcher_stop]} && #{config.scripts[:watcher_start]}")
|
118
|
+
when 'docker'
|
119
|
+
Process.kill('INT', 1) rescue nil
|
120
|
+
end
|
82
121
|
end
|
83
122
|
|
84
123
|
private
|
@@ -91,6 +130,10 @@ module Adminix
|
|
91
130
|
System.instance
|
92
131
|
end
|
93
132
|
|
133
|
+
def file_lines_number(file_path)
|
134
|
+
`wc -l #{file_path}`.to_i
|
135
|
+
end
|
136
|
+
|
94
137
|
def execute_command(key, process_id, args)
|
95
138
|
command = config.commands.find { |c| c['key'] == key }
|
96
139
|
script = command['command'].dup
|
data/lib/adminix/setup/routes.rb
CHANGED
@@ -85,6 +85,10 @@ module Adminix::Setup
|
|
85
85
|
secret_key = Services.get_secret_key(params[:t])
|
86
86
|
if id_is_valid && !secret_key.nil?
|
87
87
|
Services.import_settings(secret_key, params[:id])
|
88
|
+
Thread.start do
|
89
|
+
sleep(2)
|
90
|
+
Adminix::Service.instance.restart!
|
91
|
+
end
|
88
92
|
render('complete')
|
89
93
|
else
|
90
94
|
render('error')
|
@@ -101,7 +105,7 @@ module Adminix::Setup
|
|
101
105
|
end
|
102
106
|
|
103
107
|
set :bind, '0.0.0.0'
|
104
|
-
set :port, Adminix::Config
|
108
|
+
set :port, Adminix::Config::DEFAULT_SETUP_SERVER_PORT
|
105
109
|
|
106
110
|
run!
|
107
111
|
end
|
@@ -127,10 +127,11 @@ module Adminix::Setup
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def self.import_settings(secret_key, service_id)
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
config = Adminix::Config.instance
|
131
|
+
config.service_id = service_id
|
132
|
+
config.secret_key = secret_key
|
133
|
+
config.export_credentials
|
134
|
+
|
134
135
|
true
|
135
136
|
end
|
136
137
|
end
|
data/lib/adminix/version.rb
CHANGED
data/lib/adminix/watcher.rb
CHANGED
@@ -13,30 +13,41 @@ module Adminix
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
SYNC_PERIOD = 5.freeze
|
17
|
-
DEFAULT_WEBSOCKET_HOST = 'wss://api.adminix.io/websocket'.freeze
|
18
16
|
SERVICE_CHANNEL = 'ServiceChannel'.freeze
|
19
17
|
|
20
18
|
def initialize(opts)
|
19
|
+
@sync_period = config.watcher_sync_period
|
21
20
|
@pid_full = '/tmp/adminix.pid'
|
22
21
|
@service = Service.instance
|
23
22
|
|
24
23
|
@ws_client = nil
|
25
|
-
|
26
|
-
@ws_uri = "#{ws_path}?secret_key=#{config.secret_key}"
|
24
|
+
@ws_uri = "#{config.websocket_path}?secret_key=#{config.secret_key}"
|
27
25
|
@ws_channel = { channel: 'ServiceChannel', service_id: @service.id }
|
26
|
+
@ws_logs_channel = { channel: 'LogsChannel', service_id: @service.id }
|
27
|
+
|
28
|
+
@watching_files = []
|
29
|
+
|
30
|
+
if EM.epoll?
|
31
|
+
EM.epoll
|
32
|
+
elsif EM.kqueue?
|
33
|
+
EM.kqueue
|
34
|
+
else
|
35
|
+
Kernel.warn('Neither epoll nor kqueue are supported.')
|
36
|
+
end
|
28
37
|
end
|
29
38
|
|
30
39
|
def run!
|
31
40
|
trap_signal
|
32
|
-
|
41
|
+
|
42
|
+
Adminix::Service.instance.count_logs_lines
|
43
|
+
|
33
44
|
EventMachine.run do
|
34
45
|
@ws_client = ActionCableClient.new(@ws_uri, @ws_channel)
|
35
46
|
@ws_client.connected do |msg|
|
36
|
-
puts '
|
47
|
+
puts 'Service connection established'
|
37
48
|
end
|
38
49
|
@ws_client.disconnected do
|
39
|
-
system.log '
|
50
|
+
system.log 'Service disconnected. Reconnecting...'
|
40
51
|
sleep(2)
|
41
52
|
@ws_client.connect!
|
42
53
|
end
|
@@ -48,9 +59,30 @@ module Adminix
|
|
48
59
|
end
|
49
60
|
end
|
50
61
|
|
51
|
-
|
62
|
+
@ws_logs_client = ActionCableClient.new(@ws_uri, @ws_logs_channel)
|
63
|
+
@ws_logs_client.connected do |msg|
|
64
|
+
puts 'Logs connection established'
|
65
|
+
end
|
66
|
+
@ws_logs_client.disconnected do
|
67
|
+
system.log 'Logs disconnected. Reconnecting...'
|
68
|
+
sleep(2)
|
69
|
+
@ws_logs_client.connect!
|
70
|
+
end
|
71
|
+
@ws_logs_client.received { |msg| }
|
72
|
+
|
73
|
+
# Sync watcher
|
74
|
+
EventMachine.add_periodic_timer(config.watcher_sync_period) do
|
52
75
|
@ws_client.perform(:sync, @service.to_cable) if @ws_client.subscribed?
|
53
76
|
end
|
77
|
+
|
78
|
+
# Logs watcher
|
79
|
+
config.watch_log_files.each do |file_path|
|
80
|
+
EventMachine.watch_file(file_path, Adminix::LogWatchHandler)
|
81
|
+
end
|
82
|
+
|
83
|
+
EventMachine.add_periodic_timer(config.logs_sync_period) do
|
84
|
+
Adminix::Service.instance.sync_logs(@ws_logs_client)
|
85
|
+
end
|
54
86
|
end
|
55
87
|
end
|
56
88
|
|
data/lib/adminix.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: adminix
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.25
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Christian Dyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: eventmachine
|
@@ -157,6 +157,7 @@ files:
|
|
157
157
|
- lib/adminix.rb
|
158
158
|
- lib/adminix/.service.rb.swn
|
159
159
|
- lib/adminix/config.rb
|
160
|
+
- lib/adminix/log_watch_handler.rb
|
160
161
|
- lib/adminix/service.rb
|
161
162
|
- lib/adminix/setup.rb
|
162
163
|
- lib/adminix/setup/routes.rb
|