teuton-server 0.0.1
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/bin/teuton-server +13 -0
- data/lib/teuton-server.rb +45 -0
- data/lib/teuton-server/application.rb +6 -0
- data/lib/teuton-server/files/teuton-server.yaml +9 -0
- data/lib/teuton-server/input_loader.rb +28 -0
- data/lib/teuton-server/service.rb +97 -0
- data/lib/teuton-server/service_manager.rb +41 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0d9853aa98d950aa4f90e783c40779982b7f63b3478289b9c1f70b9bf47d1170
|
4
|
+
data.tar.gz: f8a893026600c7b750048bed1a6e9d06364a0975cbb91b9940477e53dd1d271d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 733b1cfcf1d3dae9a3e8159069635030eeb08075546228c4e82ed0e0274fd793fefa0e719a5761143896e3f8c5edd0e7377be6c9c32229ea607e57c0bdb27430
|
7
|
+
data.tar.gz: 4921d39dd197c385d9be7389eea473a8cfe817f965ab8334232e17003c2a48fab211f2592325a4b4bba0542d9b4c58c5fc64a0f48ec8a787d42b564708fa73fc
|
data/bin/teuton-server
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'teuton-server'
|
4
|
+
|
5
|
+
# TeutonServer has these main actions:
|
6
|
+
# * help => show_help
|
7
|
+
# * version => show_version
|
8
|
+
# * init => init or create server config file
|
9
|
+
# * start => Start Teuton Server
|
10
|
+
TeutonServer.show_help if ARGV.first == 'help'
|
11
|
+
TeutonServer.show_version if ARGV.first == 'version'
|
12
|
+
TeutonServer.init(ARGV) if ARGV.first == 'init'
|
13
|
+
TeutonServer.start(ARGV)
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rainbow'
|
3
|
+
require_relative 'teuton-server/application'
|
4
|
+
require_relative 'teuton-server/input_loader'
|
5
|
+
require_relative 'teuton-server/service_manager'
|
6
|
+
|
7
|
+
module TeutonServer
|
8
|
+
def self.start(args)
|
9
|
+
param = InputLoader.read_input_args(args)
|
10
|
+
ServiceManager.start_services(param)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.show_help
|
14
|
+
puts "Usage:"
|
15
|
+
puts " teuton-server [help|version] [PATH/TO/server.yaml [IP]]"
|
16
|
+
puts "Params:"
|
17
|
+
puts " help , Show this help"
|
18
|
+
puts " version , Show current version"
|
19
|
+
puts " init , Create server.yaml config file"
|
20
|
+
puts " CONFIGFILE, YAML server configuration file"
|
21
|
+
puts "Example:"
|
22
|
+
puts " Start TeutonServer using 192.168.1.16 IP:"
|
23
|
+
puts " teuton-server server.yaml 192.168.1.16"
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.show_version
|
28
|
+
puts "teuton-server => " + Rainbow("version #{Application::VERSION}").cyan
|
29
|
+
exit 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.init(arg)
|
33
|
+
src = File.join(File.dirname(__FILE__), 'teuton-server', 'files',
|
34
|
+
Application::CONFIGFILE)
|
35
|
+
dest = File.join(Application::CONFIGFILE)
|
36
|
+
if File.exists? dest
|
37
|
+
puts "teuton-server => " + Rainbow("File \'#{dest}\' exists!").red
|
38
|
+
exit 1
|
39
|
+
end
|
40
|
+
FileUtils.cp(src, dest)
|
41
|
+
puts "teuton-server => " + Rainbow("Init \'#{dest}\' done!").yellow
|
42
|
+
exit 0
|
43
|
+
# TODO: a = Dir.glob(File.join('projects/gnulinux-basic/**','start.rb'))
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative 'application'
|
3
|
+
|
4
|
+
module InputLoader
|
5
|
+
def self.read_input_args(args)
|
6
|
+
input = (args.size.zero? ? [Application::CONFIGFILE] : args)
|
7
|
+
param = {}
|
8
|
+
param = read_yaml(input[0])
|
9
|
+
param[:server][:ip] = input[1] if input[1]
|
10
|
+
param[:server][:ip] = '127.0.0.1' if param[:server][:ip].nil?
|
11
|
+
param[:server][:port] = input[2] if input[2]
|
12
|
+
param[:server][:port] = Application::PORT if param[:server][:port].nil?
|
13
|
+
param
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.read_yaml(filepath)
|
17
|
+
filepath = File.join(filepath,
|
18
|
+
Application::CONFIGFILE) if File.directory? filepath
|
19
|
+
unless File.exists? filepath
|
20
|
+
puts Rainbow("[ERROR] Config file \'#{filepath}\' not found!").red
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
param = YAML.load_file(filepath)
|
24
|
+
param[:server][:configfile] = filepath
|
25
|
+
param[:server][:configdir] = File.dirname(filepath)
|
26
|
+
param
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'socket'
|
2
|
+
|
3
|
+
class Service
|
4
|
+
def run(param)
|
5
|
+
service = TCPServer.open(param[:server][:port])
|
6
|
+
accept_clients service, param
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def accept_clients(service, param)
|
12
|
+
puts Rainbow("teuton-server => service [#{param[:client][:id]}] " +
|
13
|
+
"listening on \'#{param[:server][:port]}\'...").bright
|
14
|
+
#puts " #{service.addr}"
|
15
|
+
@actions = []
|
16
|
+
@testindex = 0
|
17
|
+
loop {
|
18
|
+
client = service.accept
|
19
|
+
if authorized_request?(client, param)
|
20
|
+
@actions << accept_request(client, param, @testindex)
|
21
|
+
else
|
22
|
+
@actions << deny_request(client, param)
|
23
|
+
end
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def authorized_request?(client, param)
|
28
|
+
return param[:client][:ip] == client.peeraddr[2]
|
29
|
+
end
|
30
|
+
|
31
|
+
def deny_request(client, param)
|
32
|
+
puts Rainbow("teuton-server => service [#{param[:client][:id]}] " +
|
33
|
+
"listening on \'#{param[:server][:port]}\'...").bright
|
34
|
+
puts " " +
|
35
|
+
Rainbow("WARN: Request not authorized " +
|
36
|
+
"\'#{client.peeraddr[2]}:#{param[:server][:port]}\'").yellow
|
37
|
+
client.puts Rainbow('Request denied from TeutonServer!').yellow
|
38
|
+
client.close
|
39
|
+
action = {}
|
40
|
+
action[:timestamp] = Time.now
|
41
|
+
action[:status] = 'Request denied'
|
42
|
+
action
|
43
|
+
end
|
44
|
+
|
45
|
+
def accept_request(client, param, testindex)
|
46
|
+
action = run_local_action(param, testindex)
|
47
|
+
respond_to_client client, param, action
|
48
|
+
action
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_local_action(param, testindex)
|
52
|
+
testname = param[:server][:testunits][testindex]
|
53
|
+
file = File.join(param[:server][:configdir], testname)
|
54
|
+
id = param[:client][:id]
|
55
|
+
command = "teuton play --quiet --case=#{id} #{file}"
|
56
|
+
ok = system(command)
|
57
|
+
action = {}
|
58
|
+
action[:timestamp] = Time.now
|
59
|
+
action[:cmd] = command
|
60
|
+
action[:grade] = Rainbow('FAIL!').red
|
61
|
+
action[:grade] = get_grade_from_report(param, testindex) if ok
|
62
|
+
action
|
63
|
+
end
|
64
|
+
|
65
|
+
def get_grade_from_report(param, testindex)
|
66
|
+
testname = param[:server][:testunits][testindex]
|
67
|
+
id = param[:client][:id]
|
68
|
+
id_tos = (id > 9 ? id.to_s : format('%02d',id))
|
69
|
+
report_path = File.join('var', testname, "case-#{id_tos}.txt")
|
70
|
+
return 'Unkown' unless File.exists? report_path
|
71
|
+
grade = `cat #{report_path} | grep grade`
|
72
|
+
grade.chop!.gsub!('|','').gsub!(' ','').gsub!('grade','')
|
73
|
+
return grade
|
74
|
+
end
|
75
|
+
|
76
|
+
def respond_to_client(client, param, action)
|
77
|
+
#puts " ADDR : #{client.addr}"
|
78
|
+
#puts " PEERADDR : #{client.peeraddr}"
|
79
|
+
puts Rainbow("teuton-server => working... " +
|
80
|
+
"service[#{param[:client][:id]}]").bright
|
81
|
+
src = "#{param[:server][:ip]}:#{param[:server][:port]}"
|
82
|
+
dest = "#{param[:client][:ip]}:#{client.peeraddr[1]}"
|
83
|
+
tab = ' '
|
84
|
+
|
85
|
+
output = tab + "Members : #{param[:client][:members]}\n" +
|
86
|
+
tab + "Connection : #{src} -> #{dest}\n" +
|
87
|
+
tab + "Timestamp : #{action[:timestamp]}\n" +
|
88
|
+
tab + "Action : #{action[:cmd]}\n" +
|
89
|
+
tab + "Grade : #{action[:grade]}\n"
|
90
|
+
puts output
|
91
|
+
client.puts("Connection : #{src} -> #{dest} ")
|
92
|
+
client.puts("Timestamp : #{action[:timestamp]}")
|
93
|
+
client.puts("Action : #{action[:cmd]}")
|
94
|
+
client.puts("Grade : #{action[:grade]}")
|
95
|
+
client.close
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
require_relative 'service'
|
3
|
+
|
4
|
+
module ServiceManager
|
5
|
+
def self.start_services(app_param)
|
6
|
+
show_starting(app_param)
|
7
|
+
services_param = split_app_param_into_services_param(app_param)
|
8
|
+
services = []
|
9
|
+
begin
|
10
|
+
services_param.each do |param|
|
11
|
+
services << Thread.new{ Service.new.run(param) }
|
12
|
+
end
|
13
|
+
services.each { |service| service.join }
|
14
|
+
rescue SystemExit, Interrupt
|
15
|
+
puts Rainbow("\nteuton-server => Closing...").bright
|
16
|
+
exit 0
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.show_starting(param)
|
21
|
+
puts Rainbow("teuton-server => Starting...").bright
|
22
|
+
puts " Configfile : #{param[:server][:configfile]}"
|
23
|
+
puts " Listen on : #{param[:server][:ip]}:#{param[:server][:port]}"
|
24
|
+
puts " Test list : #{param[:server][:testunits].join(',')}"
|
25
|
+
puts Rainbow(" (CTRL+C to exit)").bright.yellow
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.split_app_param_into_services_param(app_param)
|
29
|
+
services_param = []
|
30
|
+
app_param[:clients].each_with_index do |client, index|
|
31
|
+
param = { server: {}, client: {} }
|
32
|
+
param[:server].merge! app_param[:server] if app_param[:server]
|
33
|
+
param[:server][:hostname] = param[:server][:ip]
|
34
|
+
param[:client].merge! client
|
35
|
+
param[:client][:id] = index + 1
|
36
|
+
param[:server][:port] += param[:client][:id]
|
37
|
+
services_param << param
|
38
|
+
end
|
39
|
+
services_param
|
40
|
+
end
|
41
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: teuton-server
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Vargas Ruiz
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rainbow
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.11'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.11'
|
41
|
+
description: TeutonServer listens and responds TeutonClients request
|
42
|
+
email: teuton.software@protonmail.com
|
43
|
+
executables:
|
44
|
+
- teuton-server
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- bin/teuton-server
|
49
|
+
- lib/teuton-server.rb
|
50
|
+
- lib/teuton-server/application.rb
|
51
|
+
- lib/teuton-server/files/teuton-server.yaml
|
52
|
+
- lib/teuton-server/input_loader.rb
|
53
|
+
- lib/teuton-server/service.rb
|
54
|
+
- lib/teuton-server/service_manager.rb
|
55
|
+
homepage: https://github.com/dvarrui/teuton-server
|
56
|
+
licenses:
|
57
|
+
- GPL-3.0
|
58
|
+
metadata: {}
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubygems_version: 3.0.3
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: TeutonServer (Teuton Software)
|
78
|
+
test_files: []
|