adminix 0.1.24 → 0.1.25

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 323d686c0df911e68419b1d4a094d07517fc1728
4
- data.tar.gz: b0b3a2c75899feceaa21a2e2cab960475293edbf
3
+ metadata.gz: ed51b6024e1e9da59e6f64d6ec5dc5187d59bd46
4
+ data.tar.gz: d595961de804152a6d571b761e749a0a6ef65f14
5
5
  SHA512:
6
- metadata.gz: '061087a77def56a10ad4f6c47284d609da99a36783ab271a57e3f488176470ef170dee6ff14f2faf05b5444d37b7f09034c7f132cc3dcdf571e36862a766005a'
7
- data.tar.gz: 8c803731f17b32992c68714e9675e5611c5d7df6a2e149faf6375add59a8281e455af6f8f2170ab66cb61d08b8af8335e35b391a4dbb7ee883e2e42ac33845ee
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
- if !config.credentials_defined? && config.creds_file_exists?
52
- config.read_creds_file
53
- end
51
+ config.read_local_config
54
52
  end
55
53
 
56
54
  case options[:action]
@@ -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
- self.host = ENV['ADMINIX_HOST'] || DEFAULT_HOST
15
- self.setup_server_port = ENV['ADMINIX_SETUP_SERVER_PORT'] || DEFAULT_SETUP_SERVER_PORT
16
- self.commands = []
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
- unless data.nil?
24
- self.service_id ||= data['service_id']
25
- self.secret_key ||= data['secret_key']
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
- true
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?("#{ENV['HOME']}/.adminix")
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
+
@@ -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
- attr_reader :id, :process_id
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}/api/v1/services/#{id}/options")
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
- Process.kill('INT', 1) rescue nil
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
@@ -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.instance.setup_server_port
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
- open("#{ENV['HOME']}/.adminix", 'w') do |f|
131
- f.puts({ secret_key: secret_key, service_id: service_id }.to_json)
132
- end
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
@@ -1,3 +1,3 @@
1
1
  module Adminix
2
- VERSION = "0.1.24"
2
+ VERSION = "0.1.25"
3
3
  end
@@ -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
- ws_path = opts[:websocket_host] || ENV['ADMINIX_WEBSOCKET_HOST'] || DEFAULT_WEBSOCKET_HOST
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 'Connection established'
47
+ puts 'Service connection established'
37
48
  end
38
49
  @ws_client.disconnected do
39
- system.log 'Disconnected. Reconnecting...'
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
- EventMachine.add_periodic_timer(SYNC_PERIOD) do
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
@@ -2,6 +2,7 @@ require 'adminix/version'
2
2
  require 'adminix/config'
3
3
  require 'adminix/service'
4
4
  require 'adminix/system'
5
+ require 'adminix/log_watch_handler'
5
6
  require 'adminix/watcher'
6
7
 
7
8
  module Adminix
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.24
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-06-18 00:00:00.000000000 Z
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