evesync 1.0.2
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 +7 -0
- data/LICENSE +25 -0
- data/Rakefile +83 -0
- data/bin/evedatad +34 -0
- data/bin/evehand +36 -0
- data/bin/evemond +42 -0
- data/bin/evesync +164 -0
- data/bin/evesyncd +44 -0
- data/bin/start +16 -0
- data/config/example.conf +58 -0
- data/lib/evesync/config.rb +63 -0
- data/lib/evesync/constants.rb +17 -0
- data/lib/evesync/database.rb +107 -0
- data/lib/evesync/discover.rb +77 -0
- data/lib/evesync/err.rb +25 -0
- data/lib/evesync/handler/file.rb +28 -0
- data/lib/evesync/handler/package.rb +30 -0
- data/lib/evesync/handler.rb +89 -0
- data/lib/evesync/ipc/client.rb +37 -0
- data/lib/evesync/ipc/data/file.rb +64 -0
- data/lib/evesync/ipc/data/hashable.rb +74 -0
- data/lib/evesync/ipc/data/ignore.rb +22 -0
- data/lib/evesync/ipc/data/package.rb +58 -0
- data/lib/evesync/ipc/data/utils.rb +14 -0
- data/lib/evesync/ipc/data.rb +50 -0
- data/lib/evesync/ipc/ipc.rb +42 -0
- data/lib/evesync/ipc/server.rb +56 -0
- data/lib/evesync/log.rb +66 -0
- data/lib/evesync/ntp.rb +16 -0
- data/lib/evesync/os/linux/arch/package_manager.rb +29 -0
- data/lib/evesync/os/linux/arch/package_watcher.rb +59 -0
- data/lib/evesync/os/linux/arch.rb +2 -0
- data/lib/evesync/os/linux/base_package_manager.rb +80 -0
- data/lib/evesync/os/linux/deb/dpkg.rb +30 -0
- data/lib/evesync/os/linux/deb/package_manager.rb +38 -0
- data/lib/evesync/os/linux/deb/package_watcher.rb +32 -0
- data/lib/evesync/os/linux/deb.rb +2 -0
- data/lib/evesync/os/linux/rhel/package_manager.rb +42 -0
- data/lib/evesync/os/linux/rhel/package_watcher.rb +32 -0
- data/lib/evesync/os/linux/rhel/rpm.rb +41 -0
- data/lib/evesync/os/linux/rhel.rb +3 -0
- data/lib/evesync/os/linux.rb +9 -0
- data/lib/evesync/os.rb +2 -0
- data/lib/evesync/sync.rb +209 -0
- data/lib/evesync/trigger/base.rb +56 -0
- data/lib/evesync/trigger/file.rb +20 -0
- data/lib/evesync/trigger/package.rb +20 -0
- data/lib/evesync/trigger.rb +106 -0
- data/lib/evesync/utils.rb +51 -0
- data/lib/evesync/watcher/file.rb +156 -0
- data/lib/evesync/watcher/interface.rb +21 -0
- data/lib/evesync/watcher/package.rb +8 -0
- data/lib/evesync/watcher.rb +68 -0
- data/lib/evesync.rb +3 -0
- metadata +198 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9a1973a7b7ed425602bbb593496479cfb6ce24e57d5f490ee2d54c52e76375cb
|
4
|
+
data.tar.gz: a593092487578200014b495d75a77c20a9798525d00fe9e9ab94ed26b4eba8fd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b06baf168fac9f60cc20995b586712b1de0cf1f13ab32be858d916686d4a770ea67eba82f9b0967bee7b6cc1d664f788d5c4717489320d224a1f2e724ac1ad4c
|
7
|
+
data.tar.gz: 7178b8ffc3f5a120438ffd5a0ea1a61fbb3c1a2b9b4b55a90242fadd5b2abcc61379af372bd1575551076b59583d3472faab46214f4c9b3c5687cacf83cfd424
|
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
BSD 2-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2018, Valentine Kiselev
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Rakefile
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require 'find'
|
3
|
+
require 'mkmf'
|
4
|
+
require_relative 'lib/evesync'
|
5
|
+
VERSION = Evesync::VERSION
|
6
|
+
GEMSPEC = 'evesync.gemspec'.freeze
|
7
|
+
GEMFILE = "evesync-#{VERSION}.gem".freeze
|
8
|
+
|
9
|
+
task default: %i[lint build]
|
10
|
+
|
11
|
+
task :lint do
|
12
|
+
sh 'rubocop -l lib' if find_executable 'rubocop'
|
13
|
+
end
|
14
|
+
|
15
|
+
task :rdoc do
|
16
|
+
sh 'rdoc --ri'
|
17
|
+
sh 'rdoc'
|
18
|
+
end
|
19
|
+
|
20
|
+
task install: [GEMFILE] do
|
21
|
+
sh "gem install --local #{GEMFILE}"
|
22
|
+
end
|
23
|
+
|
24
|
+
task build: GEMFILE
|
25
|
+
file GEMFILE do
|
26
|
+
sh "gem build #{GEMSPEC}"
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec::Core::RakeTask.new(:spec)
|
30
|
+
|
31
|
+
task test: :spec
|
32
|
+
|
33
|
+
task :clean, [:remove_rpm] do |_t, args|
|
34
|
+
args.with_defaults(:remove_rpm => 1)
|
35
|
+
rm_rf('tmp')
|
36
|
+
rm_rf('doc')
|
37
|
+
rm_rf('mkmf.log')
|
38
|
+
rm_rf(Dir['*.zip'])
|
39
|
+
rm_rf('RPM') if args[:remove_rpm] == 1
|
40
|
+
rm_rf("evesync-#{VERSION}")
|
41
|
+
rm_rf(GEMFILE)
|
42
|
+
end
|
43
|
+
|
44
|
+
task todos: :todo
|
45
|
+
task :todo do
|
46
|
+
puts "==== \033[0;31mTODOs\033[0m in code"
|
47
|
+
puts `find bin lib dockerfiles -type f -exec grep --color=always TODO \{} \+ ||:`
|
48
|
+
puts "==== \033[0;31mFIXMEs\033[0m in code"
|
49
|
+
puts `find bin lib dockerfiles -type f -exec grep --color=always FIXME \{} \+ ||:`
|
50
|
+
end
|
51
|
+
|
52
|
+
task :lines do
|
53
|
+
sh 'find . -name "*.rb" -exec grep -v -E "^\s*#|^\s*$" \{} \+ | wc -l'
|
54
|
+
end
|
55
|
+
|
56
|
+
## Docker related targets
|
57
|
+
|
58
|
+
task :docker do
|
59
|
+
sh 'docker-compose build'
|
60
|
+
end
|
61
|
+
|
62
|
+
task :up do
|
63
|
+
sh 'docker-compose up -d'
|
64
|
+
end
|
65
|
+
|
66
|
+
task :down do
|
67
|
+
sh 'docker-compose stop || docker-compose kill ||:'
|
68
|
+
sh 'docker-compose rm --force ||:'
|
69
|
+
end
|
70
|
+
|
71
|
+
task :rpm do
|
72
|
+
sh("rpmbuild -bb "\
|
73
|
+
"--define 'VERSION #{VERSION}' "\
|
74
|
+
"--define 'RELEASE `git rev-list HEAD master --count`' "\
|
75
|
+
"--define '_builddir #{Dir.pwd}' "\
|
76
|
+
"--define '_rpmdir #{Dir.pwd}/RPM/' "\
|
77
|
+
"evesync.spec")
|
78
|
+
sh('chown -R 1000:1000 RPM')
|
79
|
+
end
|
80
|
+
|
81
|
+
task :'build-rpm' do
|
82
|
+
sh('echo rake rpm | docker-compose run build-centos')
|
83
|
+
end
|
data/bin/evedatad
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby -*-
|
3
|
+
|
4
|
+
require 'evesync/ipc/server'
|
5
|
+
require 'evesync/log'
|
6
|
+
require 'evesync/database'
|
7
|
+
|
8
|
+
Evesync::Log.info('Database daemon starting...')
|
9
|
+
|
10
|
+
database = Evesync::Database.new
|
11
|
+
|
12
|
+
# Creating an IPC server to accept data
|
13
|
+
data_server = Evesync::IPC::Server.new(
|
14
|
+
port: :evedatad,
|
15
|
+
proxy: database
|
16
|
+
).start
|
17
|
+
|
18
|
+
Signal.trap('TERM') do
|
19
|
+
data_server.stop
|
20
|
+
exit(0)
|
21
|
+
end
|
22
|
+
|
23
|
+
Evesync::Log.info('Database daemon started!')
|
24
|
+
|
25
|
+
begin
|
26
|
+
loop do
|
27
|
+
sleep 3600 # FIXME: 1 hour, rewrite better
|
28
|
+
# zip db if needed, save backup
|
29
|
+
end
|
30
|
+
rescue SignalException => e
|
31
|
+
data_server.stop
|
32
|
+
Evesync::Log.warn("Database daemon received signal: #{e.signm}(#{e.signo})")
|
33
|
+
exit(0)
|
34
|
+
end
|
data/bin/evehand
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby -*-
|
3
|
+
|
4
|
+
require 'evesync/log'
|
5
|
+
require 'evesync/ipc/server'
|
6
|
+
require 'evesync/handler'
|
7
|
+
|
8
|
+
Evesync::Log.info('Handle daemon starting...')
|
9
|
+
|
10
|
+
all_handler = Evesync::Handler.new
|
11
|
+
|
12
|
+
handler_server = Evesync::IPC::Server.new(
|
13
|
+
port: :evehand,
|
14
|
+
proxy: all_handler,
|
15
|
+
ip: '*' # accept remote requests
|
16
|
+
).start
|
17
|
+
|
18
|
+
Evesync::Log.info('Handle daemon started!')
|
19
|
+
|
20
|
+
# Signal handling
|
21
|
+
|
22
|
+
Signal.trap('TERM') do
|
23
|
+
handler_server.stop
|
24
|
+
exit(0)
|
25
|
+
end
|
26
|
+
|
27
|
+
begin
|
28
|
+
loop do
|
29
|
+
sleep 3600 # FIXME: 1 hour, rewrite better
|
30
|
+
# FIXME: know what to do
|
31
|
+
end
|
32
|
+
rescue SignalException => e
|
33
|
+
handler_server.stop
|
34
|
+
Evesync::Log.warn("Received signal: #{e.signm}(#{e.signo})")
|
35
|
+
exit(0)
|
36
|
+
end
|
data/bin/evemond
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby -*-
|
3
|
+
|
4
|
+
require 'evesync/log'
|
5
|
+
require 'evesync/ipc/server'
|
6
|
+
require 'evesync/trigger'
|
7
|
+
require 'evesync/watcher'
|
8
|
+
|
9
|
+
Evesync::Log.info 'Monitoring daemon starting...'
|
10
|
+
|
11
|
+
queue = Queue.new
|
12
|
+
trigger = Evesync::Trigger.new(queue)
|
13
|
+
watcher = Evesync::Watcher.new(queue)
|
14
|
+
|
15
|
+
[trigger, watcher].each(&:start)
|
16
|
+
|
17
|
+
evesync_server = Evesync::IPC::Server.new(
|
18
|
+
port: :evemond,
|
19
|
+
proxy: trigger
|
20
|
+
).start
|
21
|
+
|
22
|
+
Evesync::Log.info 'Monitoring daemon started!'
|
23
|
+
|
24
|
+
# Signal handling
|
25
|
+
|
26
|
+
Signal.trap('SIGINT') do
|
27
|
+
[watcher, trigger].each(&:stop)
|
28
|
+
evesync_server.stop
|
29
|
+
exit(0)
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
loop do
|
34
|
+
sleep 100
|
35
|
+
# FIXME: know what to do
|
36
|
+
end
|
37
|
+
rescue SignalException => e
|
38
|
+
watcher.stop
|
39
|
+
evesync_server.stop
|
40
|
+
Evesync::Log.warn("Monitoring daemon received signal: #{e.signm}(#{e.signo})")
|
41
|
+
exit(0)
|
42
|
+
end
|
data/bin/evesync
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby -*-
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
require 'socket'
|
6
|
+
require 'find'
|
7
|
+
require 'zip'
|
8
|
+
require 'evesync'
|
9
|
+
require 'evesync/log'
|
10
|
+
require 'evesync/utils'
|
11
|
+
require 'evesync/database'
|
12
|
+
require 'evesync/config'
|
13
|
+
require 'evesync/sync'
|
14
|
+
require 'evesync/ipc/client'
|
15
|
+
|
16
|
+
DB_TAG = 'db'
|
17
|
+
FILES_TAG = 'files'
|
18
|
+
|
19
|
+
opts = {}
|
20
|
+
$program = File.basename($0)
|
21
|
+
#Evesync::Log.level = :warn
|
22
|
+
Evesync::Log.simple = true
|
23
|
+
|
24
|
+
OptionParser.new do |parser|
|
25
|
+
parser.banner = "#{$program} [OPTIONS...]
|
26
|
+
|
27
|
+
"
|
28
|
+
parser.summary_width = 20
|
29
|
+
|
30
|
+
parser.on('-l', '--load FILE', 'Load events from file') do |f|
|
31
|
+
unless File.file? f
|
32
|
+
puts "File is absent: #{f}"
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
opts['load_file'] = f
|
36
|
+
end
|
37
|
+
|
38
|
+
parser.on('-z', '--zip [DEST]', 'Zip current database') do |d|
|
39
|
+
|
40
|
+
# Pretty default name
|
41
|
+
hostname = Socket.gethostname
|
42
|
+
hostname = hostname == 'localhost' \
|
43
|
+
? Evesync::Utils::local_ip : hostname
|
44
|
+
time_now = Time.now.strftime('%Y.%m.%d-%H:%M:%S')
|
45
|
+
opts['zip'] = d || "#{$program}_#{hostname}_#{time_now}.zip"
|
46
|
+
|
47
|
+
# Validation
|
48
|
+
unless File.directory? File.dirname opts['zip']
|
49
|
+
puts "Directory doesn't exist: #{File.dirname opts['zip']}"
|
50
|
+
exit 1
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
parser.on('-f', '--force', 'Enforce synchronization') do
|
55
|
+
opts['sync'] = true
|
56
|
+
end
|
57
|
+
|
58
|
+
parser.on_tail('-v', '--version', "Version of #{$program}") do
|
59
|
+
puts Evesync::VERSION
|
60
|
+
exit
|
61
|
+
end
|
62
|
+
|
63
|
+
parser.on_tail('-h', '--help', 'Help message') do
|
64
|
+
puts parser
|
65
|
+
exit
|
66
|
+
end
|
67
|
+
end.parse!
|
68
|
+
|
69
|
+
def force_sync
|
70
|
+
sync_client = Evesync::IPC::Client.new(
|
71
|
+
port: :evesyncd
|
72
|
+
)
|
73
|
+
sync_client.synchronize
|
74
|
+
end
|
75
|
+
|
76
|
+
def files_in(folder)
|
77
|
+
begin
|
78
|
+
Find.find(folder).collect { |file| file }
|
79
|
+
rescue StandardError
|
80
|
+
puts "No files in #{folder}"
|
81
|
+
[]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def zip(out)
|
86
|
+
databases = {
|
87
|
+
DB_TAG => {
|
88
|
+
Evesync::Config[:evedatad]['db_path'] =>
|
89
|
+
files_in(Evesync::Config[:evedatad]['db_path'])
|
90
|
+
},
|
91
|
+
FILES_TAG => {
|
92
|
+
Evesync::Config[:evedatad]['db_files_path'] =>
|
93
|
+
files_in(Evesync::Config[:evedatad]['db_files_path'])
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
Zip::File.open(out, Zip::File::CREATE) do |zip|
|
98
|
+
databases.each do |key, entries|
|
99
|
+
entries.each do |base_path, files|
|
100
|
+
files.each do |file|
|
101
|
+
relative_path = Pathname.new(file)
|
102
|
+
.relative_path_from(Pathname.new(base_path))
|
103
|
+
zip.add(File.join(key, relative_path.to_s), file)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def load_file(filename)
|
111
|
+
|
112
|
+
Dir.mktmpdir($program) do |tmpdir|
|
113
|
+
# Unpacking...
|
114
|
+
Zip::File.open(filename) do |zip|
|
115
|
+
zip.each do |entry|
|
116
|
+
entry.extract(File.join(tmpdir, entry.name))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
db_path = File.join(tmpdir, DB_TAG)
|
121
|
+
db_files_path = File.join(tmpdir, FILES_TAG)
|
122
|
+
|
123
|
+
loaded_db = Evesync::Database.new(
|
124
|
+
db_path,
|
125
|
+
db_files_path
|
126
|
+
)
|
127
|
+
|
128
|
+
local_db = Evesync::IPC::Client.new(
|
129
|
+
port: :evedatad
|
130
|
+
)
|
131
|
+
|
132
|
+
diff = Evesync::Sync::diff_missed(
|
133
|
+
v1: local_db.events,
|
134
|
+
v2: loaded_db.events
|
135
|
+
)
|
136
|
+
|
137
|
+
new_messages = loaded_db.messages(diff)
|
138
|
+
|
139
|
+
sync_client = Evesync::IPC::Client.new(
|
140
|
+
port: :evesyncd
|
141
|
+
)
|
142
|
+
|
143
|
+
sync_client.apply_events(new_messages)
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
def evesync(opts)
|
149
|
+
if opts['sync']
|
150
|
+
puts 'Synchronization enforced'
|
151
|
+
force_sync
|
152
|
+
end
|
153
|
+
|
154
|
+
if opts['load_file']
|
155
|
+
load_file opts['load_file']
|
156
|
+
end
|
157
|
+
|
158
|
+
if opts['zip']
|
159
|
+
zip(opts['zip'])
|
160
|
+
puts(opts['zip'])
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
evesync opts
|
data/bin/evesyncd
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- mode: ruby -*-
|
3
|
+
|
4
|
+
require 'evesync/log'
|
5
|
+
require 'evesync/sync'
|
6
|
+
require 'evesync/config'
|
7
|
+
require 'evesync/ipc/server'
|
8
|
+
|
9
|
+
# Exiting if `auto_discover = false'
|
10
|
+
unless Evesync::Config['auto_discover']
|
11
|
+
Evesync::Log.info('Synchronizing not required')
|
12
|
+
exit(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
Evesync::Log.info('Synchronizing daemon starting...')
|
16
|
+
|
17
|
+
sync = Evesync::Sync.new
|
18
|
+
|
19
|
+
sync_server = Evesync::IPC::Server.new(
|
20
|
+
port: :evesyncd,
|
21
|
+
proxy: sync
|
22
|
+
).start
|
23
|
+
|
24
|
+
Signal.trap('TERM') do
|
25
|
+
sync_server.stop
|
26
|
+
exit(0)
|
27
|
+
end
|
28
|
+
|
29
|
+
Evesync::Log.info('Synchronizing daemon started!')
|
30
|
+
|
31
|
+
few_seconds = Evesync::Config['discover_timeout'].to_i
|
32
|
+
|
33
|
+
sync.discover # discovering nodes
|
34
|
+
sleep 3 # giving 3 seconds to complete
|
35
|
+
|
36
|
+
begin
|
37
|
+
loop do
|
38
|
+
sync.synchronize # updating this node
|
39
|
+
sleep few_seconds # ... in some interval
|
40
|
+
end
|
41
|
+
rescue SignalException
|
42
|
+
sync_server.stop
|
43
|
+
exit(0)
|
44
|
+
end
|
data/bin/start
ADDED
data/config/example.conf
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# This is a configuration file example
|
2
|
+
# It contains all information about daemons that can be changed
|
3
|
+
# It's TOML formatted file, so feel free to use this format
|
4
|
+
# without any restrictions.
|
5
|
+
#
|
6
|
+
# For more information about TOML format see:
|
7
|
+
# - https://github.com/toml-lang/toml
|
8
|
+
# - https://en.wikipedia.org/wiki/TOML
|
9
|
+
|
10
|
+
# Available log levels:
|
11
|
+
# debug info warn error fatal
|
12
|
+
loglevel = 'debug'
|
13
|
+
# Delay in seconds for discovery package sending
|
14
|
+
discover_timeout = 600
|
15
|
+
# Automate discovering
|
16
|
+
auto_discover = true
|
17
|
+
|
18
|
+
ntp = 'us.pool.ntp.org'
|
19
|
+
|
20
|
+
[evemond] # System Monitor daemon
|
21
|
+
port = 55443
|
22
|
+
|
23
|
+
# A list of remote nodes ips to keep connected with
|
24
|
+
remotes = [ ]
|
25
|
+
|
26
|
+
# Files to watch and synchronize
|
27
|
+
watch = [
|
28
|
+
'/etc/pam.d/login',
|
29
|
+
'/etc/pam.d/other',
|
30
|
+
]
|
31
|
+
|
32
|
+
# Interval for gathering files' changes
|
33
|
+
watch_interval = 3
|
34
|
+
|
35
|
+
# TODO:
|
36
|
+
ignore_packages = [
|
37
|
+
'ruby',
|
38
|
+
]
|
39
|
+
|
40
|
+
# TODO:
|
41
|
+
ignore_files = [
|
42
|
+
'/etc/hosts',
|
43
|
+
]
|
44
|
+
|
45
|
+
|
46
|
+
[evehand] # System Handler daemon
|
47
|
+
port = 55432
|
48
|
+
|
49
|
+
|
50
|
+
[evedatad] # System Data daemon
|
51
|
+
port = 54321
|
52
|
+
|
53
|
+
[evesyncd]
|
54
|
+
port = 64653
|
55
|
+
broadcast_port = 64564
|
56
|
+
|
57
|
+
|
58
|
+
# Copyright (c) Kiselev Valentin 2019
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'toml-rb'
|
2
|
+
require 'evesync/utils'
|
3
|
+
require 'evesync/constants'
|
4
|
+
require 'evesync/log'
|
5
|
+
|
6
|
+
module Evesync
|
7
|
+
module Config
|
8
|
+
class << self
|
9
|
+
|
10
|
+
DEFAULTS = {
|
11
|
+
'ntp' => '',
|
12
|
+
'evemond' => {
|
13
|
+
'port' => Constants::MOOND_PORT,
|
14
|
+
'remotes' => [],
|
15
|
+
'watch' => [],
|
16
|
+
'watch_interval' => Constants::WATCH_INTERVAL
|
17
|
+
},
|
18
|
+
'evedatad' => {
|
19
|
+
'port' => Constants::DATAD_PORT,
|
20
|
+
'db_path' => Constants::DB_PATH,
|
21
|
+
'db_files_path' => Constants::DB_FILES_PATH
|
22
|
+
},
|
23
|
+
'evehand' => {
|
24
|
+
'port' => Constants::HAND_PORT
|
25
|
+
},
|
26
|
+
'evesyncd' => {
|
27
|
+
'port' => Constants::SYNC_PORT
|
28
|
+
},
|
29
|
+
'discover_timeout' => Constants::DISCOVER_TIMEOUT
|
30
|
+
}
|
31
|
+
|
32
|
+
|
33
|
+
def [](daemon)
|
34
|
+
read_config if needs_reading
|
35
|
+
|
36
|
+
@@config[daemon.to_s]
|
37
|
+
end
|
38
|
+
|
39
|
+
def reread
|
40
|
+
read_config
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def read_config
|
46
|
+
config = begin
|
47
|
+
TomlRB.load_file(Constants::CONFIG_FILE)
|
48
|
+
rescue StandardError => e
|
49
|
+
Log.error("Config ERROR: Couldn't parse file #{Constants::CONFIG_FILE}")
|
50
|
+
Log.error("Config ERROR MESSAGE: #{e}")
|
51
|
+
Log.error("Config ERROR: Using default configuration")
|
52
|
+
{}
|
53
|
+
end
|
54
|
+
@@config = DEFAULTS.deep_merge(config)
|
55
|
+
Log.info("Config initialized!")
|
56
|
+
end
|
57
|
+
|
58
|
+
def needs_reading
|
59
|
+
! defined? @@config
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Evesync
|
2
|
+
module Constants
|
3
|
+
MOOND_PORT = '55443'.freeze
|
4
|
+
DATAD_PORT = '54321'.freeze
|
5
|
+
HAND_PORT = '55432'.freeze
|
6
|
+
SYNC_PORT = '64653'.freeze
|
7
|
+
|
8
|
+
CONFIG_FILE = '/etc/evesync.conf'.freeze
|
9
|
+
DB_PATH = '/var/lib/evesync/db/'.freeze
|
10
|
+
DB_FILES_PATH = '/var/lib/evesync/files/'.freeze
|
11
|
+
|
12
|
+
DEFAULT_LOGLEVEL = 'debug'.freeze
|
13
|
+
|
14
|
+
DISCOVER_TIMEOUT = 3600
|
15
|
+
WATCH_INTERVAL = 2
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'json'
|
3
|
+
require 'lmdb'
|
4
|
+
require 'evesync/config'
|
5
|
+
require 'evesync/constants'
|
6
|
+
require 'evesync/ipc/data/package'
|
7
|
+
require 'evesync/ipc/data/file'
|
8
|
+
require 'evesync/ipc/data/ignore'
|
9
|
+
|
10
|
+
module Evesync
|
11
|
+
|
12
|
+
##
|
13
|
+
# *Database* class is a proxy for *evedatad* daemon
|
14
|
+
# implements at least one method: +save+. Allows
|
15
|
+
# Local +evemond+ save messages about changes
|
16
|
+
#
|
17
|
+
# Messages should be serializable (JSON)
|
18
|
+
#
|
19
|
+
# TODO:
|
20
|
+
# * Think about how it can be widened
|
21
|
+
|
22
|
+
class Database
|
23
|
+
def initialize(db_path=nil, db_files_path=nil)
|
24
|
+
path = db_path || Config[:evedatad]['db_path']
|
25
|
+
|
26
|
+
unless ::File.exist? path
|
27
|
+
# FIXME: only root. handle exception
|
28
|
+
FileUtils.mkdir_p(path)
|
29
|
+
end
|
30
|
+
@env = LMDB.new(path)
|
31
|
+
@db = @env.database
|
32
|
+
@files_path = db_files_path || Config[:evedatad]['db_files_path']
|
33
|
+
end
|
34
|
+
|
35
|
+
# Save message to database, key is timestamp+object
|
36
|
+
def save(message)
|
37
|
+
Log.debug("Database save: #{message}")
|
38
|
+
db_add_entry(message)
|
39
|
+
|
40
|
+
if message.is_a? Evesync::IPC::Data::File
|
41
|
+
Log.debug("Database save file action: #{message.action}")
|
42
|
+
unless message.action ==
|
43
|
+
IPC::Data::File::Action::DELETE
|
44
|
+
save_file(message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
# Events simplified: object => [timestamp...]
|
51
|
+
def events
|
52
|
+
events = {}
|
53
|
+
@db.each do |key, _|
|
54
|
+
timestamp, object = parse_event(key)
|
55
|
+
events[object] ||= []
|
56
|
+
events[object].push(timestamp)
|
57
|
+
end
|
58
|
+
events
|
59
|
+
end
|
60
|
+
|
61
|
+
# Messages for events: object => {timestamp => message}
|
62
|
+
def messages(events)
|
63
|
+
ev_msgs = {}
|
64
|
+
@db.each do |key, message|
|
65
|
+
timestamp, object = parse_event(key)
|
66
|
+
next unless events.include?(object)
|
67
|
+
|
68
|
+
ev_msgs[object] ||= {}
|
69
|
+
if events[object].include?(timestamp)
|
70
|
+
ev_msgs[object][timestamp] = message
|
71
|
+
end
|
72
|
+
end
|
73
|
+
ev_msgs
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def db_add_entry(message)
|
79
|
+
Log.debug('Database adding entry...')
|
80
|
+
key = create_key(message)
|
81
|
+
value = create_value(message)
|
82
|
+
@db[key] = value
|
83
|
+
Log.debug('Database adding entry done!')
|
84
|
+
end
|
85
|
+
|
86
|
+
def create_key(message)
|
87
|
+
"#{message.timestamp}_#{message.name}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def create_value(message)
|
91
|
+
message.to_hash.to_json
|
92
|
+
end
|
93
|
+
|
94
|
+
def parse_event(key)
|
95
|
+
key.split('_', 2)
|
96
|
+
end
|
97
|
+
|
98
|
+
def save_file(file)
|
99
|
+
Log.debug('Database saving file...')
|
100
|
+
fulldest = File.join(@files_path,
|
101
|
+
file.name + ".#{file.timestamp}")
|
102
|
+
FileUtils.mkdir_p(File.dirname(fulldest))
|
103
|
+
FileUtils.cp(file.name, fulldest)
|
104
|
+
Log.debug('Database saving file done!')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|