summaryrefslogtreecommitdiff
path: root/tasks/custom_rdate/task.py
diff options
context:
space:
mode:
Diffstat (limited to 'tasks/custom_rdate/task.py')
-rw-r--r--tasks/custom_rdate/task.py146
1 files changed, 146 insertions, 0 deletions
diff --git a/tasks/custom_rdate/task.py b/tasks/custom_rdate/task.py
new file mode 100644
index 0000000..4c5ff9f
--- /dev/null
+++ b/tasks/custom_rdate/task.py
@@ -0,0 +1,146 @@
+# kpov_util should be imported by add_assignment.py
+
+# TODO: finish this!
+instructions = {
+ 'si': '''\
+<p>
+Postavite dva navidezna računalnika: <em>SimpleArbiterDhcpRdate</em> in <em>rdateClient</em>.
+
+<p>
+Nastavite čas na <em>rdateClient</em> tako, da kot rdate strežnik uporabite <em>SimpleArbiterDhcpRdate</em>.
+
+<p>
+Na <em>rdateClient</em> ustvarite uporabnika <code>test</code> z geslom <code>test</code>. V domačem imeniku uporabnika <code>test</code> ustvarite program z imenom <code>{{PROGRAM_FILENAME}}</code>. Program naj prebere štiri bajte podatkov s standardnega vhoda in jih pretvori v predznačeno celo število, pri čemer naj uporablja zapis z debelim koncem (angl. <em lang="en">big endian</em>). Število naj program izpiše na standardni izhod v obliki niza.
+''',
+ 'en': '''\
+<p>
+Set up two virtual machines: <em>SimpleArbiterDhcpRdate</em> and <em>rdateClient</em>.
+
+<p>
+Set the time on <em>rdateClient</em> using rdate with <em>SimpleArbiterDhcpRdate</em> as
+the server.
+
+<p>
+On <em>rdateClient</em> create a user with the username <code>test</code> and password <code>test</code>. Then, write a program called <code>{{PROGRAM_FILENAME}}</code> and put it in user <code>test</code>’s home directory. The program should read four bytes of data from standard input, convert them into a signed integer using big endian byte ordering and output the resulting integer (as a string) to standard output.
+''',
+}
+
+computers = {
+ 'rdateClient': {
+ 'disks': [
+ { 'name': 'student-rdate',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+
+ },
+ 'SimpleArbiter': {
+ 'disks': [
+ { 'name': 'simpleArbiterDhcpGWRdate',
+ },
+ ],
+ 'network_interfaces': [{'network': 'net1'}, {'network': 'test-net'}],
+ 'flavor': 'm1.tiny',
+ 'config_drive': False
+ }
+}
+
+networks = { 'net1': {'public': False}, 'test-net': {'public': True} }
+
+# Tu sem dolocil parametre
+params_meta = {
+ 'RDATE_OFFSET':{'descriptions': {'si': 'Napaka v času pri rdate', 'en': 'Timekeeping error for rdate'}, 'w': False, 'public': False, 'type': 'integer', 'generated': True},
+ 'PROGRAM_FILENAME':{'descriptions': {'si': 'Ime programa', 'en': 'program filename'}, 'w': False, 'public': True, 'type': 'integer', 'generated': True},
+ 'IP_RDATECLIENT':{'descriptions': {'si': 'IP rdateClient', "en": "rdateClient's IP"}, 'w': True, 'public': True, 'type': 'IP', 'generated': False},
+}
+
+def task(IP_RDATECLIENT, PROGRAM_FILENAME):
+ import collections
+ import base64
+ import random
+ import struct
+ import pexpect
+
+ r = random.Random(PROGRAM_FILENAME)
+ results = collections.defaultdict(str)
+ tests = []
+ for i in range(10):
+ data = struct.pack("!I", r.randint(0, 2**32))
+ results['in_'+str(i)] = data_ascii = base64.encodestring(data)
+ tests += [('out_'+str(i), 'echo "{}" | base64 -d | ~/{}'.format(data_ascii.decode().strip(), PROGRAM_FILENAME))]
+ tests += [('date', 'date -u +"%s"')]
+
+ results.update(
+ kpov_util.ssh_test(IP_RDATECLIENT, 'test', 'test', tests))
+ results['ldate'] = pexpect.run('date -u +"%s"')
+
+ return results
+
+#Dolocil sem tri parametre in sicer jih lahko vidite v prams_meta,
+#zato prosim da jih upostevate v naslednih nalogah.
+
+def gen_params(user_id, params_meta):
+ import socket
+ import struct
+ import datetime
+ params = dict()
+ r = random.Random(user_id)
+ params['PROGRAM_FILENAME'] = kpov_util.fname_gen(r, False)
+ params['RDATE_OFFSET'] = str(r.randint(-2**24, 2**24))
+ return params
+
+def task_check(results, params):
+ import random
+ import struct
+ import base64
+
+ r = random.Random(params['PROGRAM_FILENAME'])
+ score = 0.0
+ hints = []
+ for i in range(10):
+ data = base64.decodestring(results['in_' + str(i)])
+ x = struct.pack("!I", r.randint(0, 2**32))
+ if data != x:
+ hints += ["data: " + str((data,)) + " != " + str((x,))]
+ break
+ res = results['out_' + str(i)]
+ if str(struct.unpack("!i", data)[0]) == res.strip():
+ score += 0.5
+ else:
+ hints += ["wrong convert"]
+
+ if abs(int(results['ldate']) + \
+ int(params['RDATE_OFFSET']) - int(results['date'])) < 3:
+ score += 5
+ else:
+ hints += ["wrong offset"]
+ return score, hints
+
+def prepare_disks(templates, task_params, global_params):
+ d = templates['simpleArbiterDhcpGWRdate']
+ s1 = """service "time_tcp" {{
+ enabled yes;
+ protocol tcp;
+ port "time";
+ user "nobody";
+ exec "/usr/local/bin/kpovrdate {RDATE_OFFSET}";
+ server "/usr/sbin/tcpd";
+ wait no;
+}}
+""".format(**task_params)
+ d.write('/etc/rlinetd.d/time', s1)
+ s2 = """#!/usr/bin/python
+
+import struct
+import time
+import sys
+
+offset = int(sys.argv[1])
+t = time.time() + offset # used to have + 2208988800
+sys.stdout.write(struct.pack("!I", int(t)))
+"""
+ d.write('/usr/local/bin/kpovrdate', s2)
+ d.chmod(0o775, '/usr/local/bin/kpovrdate')
+ write_default_config(templates['simpleArbiterDhcpGWRdate'], global_params)