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 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,6 @@
1
+ module Application
2
+ NAME = 'teuton-server'
3
+ VERSION = '0.0.1'
4
+ CONFIGFILE = 'teuton-server.yaml'
5
+ PORT = 16000
6
+ end
@@ -0,0 +1,9 @@
1
+ ---
2
+ :server:
3
+ :ip: 127.0.0.1
4
+ :port: 16000
5
+ :testunits:
6
+ - testname01
7
+ :clients:
8
+ - :members: client01
9
+ :ip: 127.0.0.1
@@ -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: []