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
data/lib/evesync/log.rb
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'evesync/config'
|
3
|
+
require 'evesync/constants'
|
4
|
+
|
5
|
+
# This module is responsible for logging
|
6
|
+
module Evesync
|
7
|
+
module Log
|
8
|
+
# Supported levels for logging
|
9
|
+
LEVELS = %i[debug info warn error fatal].freeze
|
10
|
+
|
11
|
+
class << self
|
12
|
+
def method_missing(m, *args)
|
13
|
+
# Unlisted methods are not allowed
|
14
|
+
raise NoMethodError unless LEVELS.include?(m)
|
15
|
+
|
16
|
+
check_logger
|
17
|
+
@logger.send(m, to_string(*args))
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def check_logger
|
22
|
+
init_logger unless @logger
|
23
|
+
end
|
24
|
+
|
25
|
+
def level=(lvl)
|
26
|
+
check_logger
|
27
|
+
if lvl.is_a?(Symbol) or lvl.is_a?(String)
|
28
|
+
@logger.level =
|
29
|
+
begin
|
30
|
+
Logger.const_get(lvl.to_s.upcase)
|
31
|
+
rescue NameError
|
32
|
+
Logger::DEBUG
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def level
|
38
|
+
check_logger
|
39
|
+
@logger.level
|
40
|
+
end
|
41
|
+
|
42
|
+
def simple=(bool)
|
43
|
+
init_logger unless @logger
|
44
|
+
if bool
|
45
|
+
@logger.formatter = proc do |_sev, _dt, _prog, msg|
|
46
|
+
"#{msg}\n"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def init_logger
|
52
|
+
@logger = Logger.new(STDERR)
|
53
|
+
@logger.formatter = proc do |sev, dtime, _prog, msg|
|
54
|
+
time = dtime.strftime('%Y-%m-%d %H:%M:%S')
|
55
|
+
prog = File.basename($PROGRAM_NAME)
|
56
|
+
"[#{time}] #{prog.ljust(8)} #{sev.ljust(5)}: #{msg}\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_string(*args)
|
61
|
+
to_s_with_space = ->(s) { "#{s} " }
|
62
|
+
args.map(&to_s_with_space).reduce(&:+).strip
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/evesync/ntp.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
module Evesync
|
2
|
+
module OS
|
3
|
+
# FIXME: pacman downgrading requires full url path
|
4
|
+
module PackageManager
|
5
|
+
class << self
|
6
|
+
def install(*args)
|
7
|
+
pacman('-Sy', *args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove(*args)
|
11
|
+
pacman('-R', *args)
|
12
|
+
end
|
13
|
+
|
14
|
+
# FIXME: update and downgrade specific version is not fine
|
15
|
+
def update(*args)
|
16
|
+
pacman('-U', *args)
|
17
|
+
end
|
18
|
+
|
19
|
+
def downgrade(*args)
|
20
|
+
pacman('-U', *args)
|
21
|
+
end
|
22
|
+
|
23
|
+
def pacman(cmd, name, _version)
|
24
|
+
`pacman #{cmd} #{name}` # FIXME: do smth with version
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'file-tail'
|
2
|
+
require 'evesync/log'
|
3
|
+
require 'evesync/config'
|
4
|
+
require 'evesync/ipc/data/package'
|
5
|
+
require 'evesync/watcher/interface'
|
6
|
+
|
7
|
+
module Evesync
|
8
|
+
module OS
|
9
|
+
|
10
|
+
# Watcher for package changes for Arch Linux
|
11
|
+
#
|
12
|
+
# = Example
|
13
|
+
# Thread.new { IPC::Data::PackageWatcher.new(queue).run }
|
14
|
+
class PackageWatcher < Watcher::Interface
|
15
|
+
ARCH_LOG_FILE = '/var/log/pacman.log'.freeze
|
16
|
+
PKG_REGEXP =
|
17
|
+
/(?<command>reinstalled|installed|removed)
|
18
|
+
\s*
|
19
|
+
(?<package>\w+)
|
20
|
+
\s*
|
21
|
+
\( (?<version>[\w\d.-]+) \)
|
22
|
+
/x.freeze
|
23
|
+
|
24
|
+
private_constant :ARCH_LOG_FILE, :PKG_REGEXP
|
25
|
+
|
26
|
+
def initialize(queue)
|
27
|
+
@queue = queue
|
28
|
+
Log.debug('Arch Package watcher initialized')
|
29
|
+
end
|
30
|
+
|
31
|
+
def start
|
32
|
+
Log.debug('Arch Package watcher started')
|
33
|
+
@thr = Thread.new do
|
34
|
+
File.open(ARCH_LOG_FILE) do |log|
|
35
|
+
log.extend(File::Tail)
|
36
|
+
log.interval = Config[:evemond]['watch-interval']
|
37
|
+
log.backward(1)
|
38
|
+
log.tail do |line|
|
39
|
+
m = line.match(PKG_REGEXP)
|
40
|
+
next unless m
|
41
|
+
|
42
|
+
pkg = IPC::Data::Package.new(
|
43
|
+
name: m[:package],
|
44
|
+
version: m[:version],
|
45
|
+
command: m[:command]
|
46
|
+
)
|
47
|
+
@queue << pkg
|
48
|
+
Log.debug 'Arch package watcher enqued:', pkg
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def stop
|
55
|
+
@thr.exit
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'hashdiff'
|
2
|
+
require 'evesync/ipc/data/package'
|
3
|
+
|
4
|
+
module Evesync
|
5
|
+
module OS
|
6
|
+
module BasePackageManager
|
7
|
+
def initialize
|
8
|
+
@packages = make_pkg_snapshot
|
9
|
+
end
|
10
|
+
|
11
|
+
def changes
|
12
|
+
# make hash of all packages
|
13
|
+
snapshot = make_pkg_snapshot
|
14
|
+
# diff with last version
|
15
|
+
diff = HashDiff.diff(@packages, snapshot)
|
16
|
+
# parse changes into IPC::Data::Package array
|
17
|
+
packages = parse_pkg_diff(diff)
|
18
|
+
# use new hash as default
|
19
|
+
# FIXME: wait if the changes were saved
|
20
|
+
# and properly handled
|
21
|
+
@packages = snapshot
|
22
|
+
packages
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Parses changes, given by 'hashdiff' gem into
|
28
|
+
# IPC::Data::Package array
|
29
|
+
def parse_pkg_diff(diffs)
|
30
|
+
packages = []
|
31
|
+
diffs.each do |diff|
|
32
|
+
package = case diff[0]
|
33
|
+
when '-' then removed_package(diff)
|
34
|
+
when '+' then installed_package(diff)
|
35
|
+
when '~' then updated_package(diff)
|
36
|
+
end
|
37
|
+
packages.push(package)
|
38
|
+
end
|
39
|
+
|
40
|
+
packages
|
41
|
+
end
|
42
|
+
|
43
|
+
def removed_package(diff)
|
44
|
+
IPC::Data::Package.new(
|
45
|
+
name: diff[1],
|
46
|
+
version: diff[2],
|
47
|
+
command: IPC::Data::Package::Command::REMOVE
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def installed_package(diff)
|
52
|
+
IPC::Data::Package.new(
|
53
|
+
name: diff[1],
|
54
|
+
version: diff[2],
|
55
|
+
command: IPC::Data::Package::Command::INSTALL
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
def updated_package(diff)
|
60
|
+
command = if pkg_version_less(diff[2], diff[3])
|
61
|
+
IPC::Data::Package::Command::UPDATE
|
62
|
+
else
|
63
|
+
IPC::Data::Package::Command::DOWNGRADE
|
64
|
+
end
|
65
|
+
|
66
|
+
IPC::Data::Package.new(
|
67
|
+
name: diff[1],
|
68
|
+
version: diff[3],
|
69
|
+
command: command
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
# FIXME:
|
74
|
+
# - research about restrictions and make sure this work
|
75
|
+
def pkg_version_less(a, b)
|
76
|
+
a < b
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'hashdiff'
|
2
|
+
require 'evesync/log'
|
3
|
+
require 'evesync/os/linux/base_package_manager'
|
4
|
+
|
5
|
+
module Evesync
|
6
|
+
module OS
|
7
|
+
class Dpkg
|
8
|
+
include BasePackageManager
|
9
|
+
|
10
|
+
PKG_QUERY = 'dpkg-query -l'.freeze
|
11
|
+
|
12
|
+
private_constant :PKG_QUERY
|
13
|
+
|
14
|
+
# Snapshot is a hash where key is a package name
|
15
|
+
# and value - it's version.
|
16
|
+
# This function returns a snapshot of a system
|
17
|
+
# package status for a moment
|
18
|
+
def make_pkg_snapshot
|
19
|
+
snapshot = {}
|
20
|
+
query_output = `#{PKG_QUERY}`
|
21
|
+
query_output.lines.each do |line|
|
22
|
+
info = line.split
|
23
|
+
snapshot[info[1]] = info[2]
|
24
|
+
end
|
25
|
+
|
26
|
+
snapshot
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Evesync
|
2
|
+
module OS
|
3
|
+
module PackageManager
|
4
|
+
class << self
|
5
|
+
def install(*args)
|
6
|
+
apt_get('install', *args)
|
7
|
+
exist?(*args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove(*args)
|
11
|
+
apt_get('remove', *args)
|
12
|
+
!exist?(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def update(*args)
|
16
|
+
apt_get('upgrade', *args)
|
17
|
+
exist?(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def downgrade(*args)
|
21
|
+
apt_get('install', *args)
|
22
|
+
exist?(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def apt_get(cmd, name, version)
|
26
|
+
Log.debug("Apt-get command: '#{cmd}' on #{name}=#{version}")
|
27
|
+
system("apt-get --assume-yes #{cmd} #{name}=#{version}")
|
28
|
+
end
|
29
|
+
|
30
|
+
def exist?(name, version)
|
31
|
+
Log.debug("Dpkg checking if exists: #{name}-#{version}")
|
32
|
+
`dpkg-query -l #{name}`
|
33
|
+
$CHILD_STATUS == 0
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'evesync/log'
|
2
|
+
require 'evesync/watcher/interface'
|
3
|
+
require_relative './dpkg'
|
4
|
+
|
5
|
+
module Evesync
|
6
|
+
module OS
|
7
|
+
class PackageWatcher < Watcher::Interface
|
8
|
+
def initialize(queue)
|
9
|
+
@queue = queue
|
10
|
+
@dpkg = Dpkg.new
|
11
|
+
Log.debug('Debian Package watcher initialized')
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
Log.debug('Debian Package watcher started')
|
16
|
+
@thr = Thread.new do
|
17
|
+
loop do
|
18
|
+
sleep 10
|
19
|
+
@dpkg.changes.each do |pkg|
|
20
|
+
@queue << pkg
|
21
|
+
Log.debug 'Debian Package watcher enqued:', pkg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop
|
28
|
+
@thr.exit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'evesync/log'
|
2
|
+
|
3
|
+
# Manages package manager things
|
4
|
+
# TODO: trigger package_watcher event to update database
|
5
|
+
module Evesync
|
6
|
+
module OS
|
7
|
+
module PackageManager
|
8
|
+
class << self
|
9
|
+
def install(*args)
|
10
|
+
return false if exist?(*args)
|
11
|
+
yum('install', *args)
|
12
|
+
exist?(*args)
|
13
|
+
end
|
14
|
+
|
15
|
+
def remove(*args)
|
16
|
+
yum('remove', *args)
|
17
|
+
!exist?(*args)
|
18
|
+
end
|
19
|
+
|
20
|
+
def update(*args)
|
21
|
+
yum('update', *args)
|
22
|
+
exist?(*args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def downgrade(*args)
|
26
|
+
yum('downgrade', *args)
|
27
|
+
exist?(*args)
|
28
|
+
end
|
29
|
+
|
30
|
+
def yum(cmd, name, version)
|
31
|
+
Log.debug("Yum command: '#{cmd}' on #{name}-#{version}")
|
32
|
+
system("yum --assumeyes #{cmd} #{name}-#{version}")
|
33
|
+
end
|
34
|
+
|
35
|
+
def exist?(name, version)
|
36
|
+
Log.debug("Yum checking if exists: #{name}-#{version}")
|
37
|
+
system("rpm -q #{name}-#{version} >/dev/null 2>&1")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative './rpm'
|
2
|
+
require 'evesync/log'
|
3
|
+
require 'evesync/watcher/interface'
|
4
|
+
|
5
|
+
module Evesync
|
6
|
+
module OS
|
7
|
+
class PackageWatcher < Watcher::Interface
|
8
|
+
def initialize(queue)
|
9
|
+
@queue = queue
|
10
|
+
@rpm_packages = Rpm.new
|
11
|
+
Log.debug('Rhel Package watcher initialized')
|
12
|
+
end
|
13
|
+
|
14
|
+
def start
|
15
|
+
Log.debug('Rhel Package watcher started')
|
16
|
+
@thr = Thread.new do
|
17
|
+
loop do
|
18
|
+
sleep 10 # FIXME: don't use magic numbers
|
19
|
+
@rpm_packages.changes.each do |pkg|
|
20
|
+
@queue << pkg
|
21
|
+
Log.debug 'Rhel Package watcher enqued:', pkg
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def stop
|
28
|
+
@thr.exit
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'evesync/log'
|
2
|
+
require 'evesync/os/linux/base_package_manager'
|
3
|
+
|
4
|
+
module Evesync
|
5
|
+
module OS
|
6
|
+
|
7
|
+
# Rpm packages changes watcher. Yum history makes it
|
8
|
+
# difficult to handler package removals. So, rpm is
|
9
|
+
# the only tool that show all packages in the system.
|
10
|
+
# This class handles packages changes.
|
11
|
+
#
|
12
|
+
# = Example:
|
13
|
+
# rpm = Evesync::Rpm.new
|
14
|
+
# sleep 1000
|
15
|
+
# rpm.changed.each do |package|
|
16
|
+
# p package # print packages that changed
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# = TODO:
|
20
|
+
# * add reinstall handling also
|
21
|
+
#
|
22
|
+
class Rpm
|
23
|
+
include BasePackageManager
|
24
|
+
# Query for rpm list
|
25
|
+
PKG_QUERY = 'rpm -qa --queryformat "%{NAME} %{VERSION}-%{RELEASE}.%{ARCH}\n"'.freeze
|
26
|
+
|
27
|
+
private_constant :PKG_QUERY
|
28
|
+
|
29
|
+
def make_pkg_snapshot
|
30
|
+
snapshot = {}
|
31
|
+
query_output = `#{PKG_QUERY}`
|
32
|
+
query_output.lines.each do |line|
|
33
|
+
info = line.split
|
34
|
+
snapshot[info[0]] = info[1]
|
35
|
+
end
|
36
|
+
|
37
|
+
snapshot
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/evesync/os.rb
ADDED