source: research/2008-displacement/main-cpushare @ 2287

Last change on this file since 2287 was 2287, checked in by Sam Hocevar, 14 years ago
  • Better error reporting and argument passing from/to the bytecode.
  • Property svn:executable set to *
File size: 4.0 KB
Line 
1#! /usr/bin/python
2
3import os, struct, sys, random
4
5import gd
6
7from cpushare.proto_const import *
8from cpushare.exceptions import CompilationError
9
10# Our input data
11source = False
12result = False
13todo = 0
14
15# Parse command line
16if len(sys.argv) < 4:
17    print 'Usage: %s <buy_order.cpu> -<mode> [image list]' % (sys.argv[0],)
18    sys.exit(-1)
19mode = sys.argv[2][1]
20done = 0
21source = sys.argv[3:]
22result = [False] * len(source)
23
24class buy_state_machine_class(object):
25    buy_api = '0.0.0'
26
27    w, h = 0, 0
28    index = -1
29    answer = ''
30
31    def __init__(self, protocol):
32        self.protocol = protocol
33        self.handler = self.stringReceived
34
35    def start(self):
36        global todo, source
37        if todo >= len(source):
38            return # We're finished... FIXME: is the transaction kept stuck?
39        self.index = todo
40        todo += 1
41        gd.gdMaxColors = 256 * 256 * 256
42        im = gd.image(source[self.index])
43        # Send argument count
44        self.protocol.sendString(PROTO_SECCOMP_FORWARD + chr(3))
45        # Send arguments
46        msg = chr(3)
47        msg += "bytecode\0"
48        msg += "-1\0"
49        msg += source[self.index] + "\0"
50        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
51        # Send image size
52        (self.w, self.h) = (w, h) = im.size()
53        print 'sending %s (%dx%d)' % (source[self.index], w, h)
54        msg = chr(w / 256) + chr(w % 256) + chr(h / 256) + chr(h % 256)
55        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
56        # Send image contents
57        msg = ''
58        for y in range(h):
59            for x in range(w):
60                p = im.getPixel((x, y))
61                rgb = im.colorComponents(p)
62                msg += chr(rgb[1]) # use green coordinate
63        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
64        print '%s bytes sent' % len(msg)
65
66    def stringReceived(self, string):
67        control = string[0]
68        data = string[1:]
69
70        if control == PROTO_SECCOMP_FORWARD:
71            self.answer += data
72            if ord(self.answer[-1]) != 0:
73                return
74            global done, result
75            result[self.index] = self.answer[:-1]
76            print self.answer[:-1],
77            self.protocol.sendString(PROTO_SECCOMP_SUCCESS)
78            done += 1
79            if done < len(source):
80                return
81            from twisted.internet import reactor
82            reactor.stop()
83        elif control == PROTO_SECCOMP_SIGNAL:
84            print 'Checkpoint starting'
85        elif control == PROTO_LOG:
86            print repr(data)
87        else:
88            if control == PROTO_SECCOMP_SUCCESS:
89                pass
90            elif control == PROTO_SECCOMP_FAILURE:
91                status = struct.unpack('!i', data)[0]
92                exit_code = status >> 8
93                signal = status & 0xff
94                s = 'Seccomp failure: status %d, exit_code %d, signal %d.' % \
95                      (status, exit_code, signal)
96                print s
97            else:
98                s = 'Unknown failure %d - %s' % (ord(control), repr(string))
99                self.protocol.sendString(PROTO_SECCOMP_FAILURE + s)
100                print s
101            self.protocol.sendString(PROTO_SECCOMP_FAILURE)
102            self.protocol.transport.loseConnection()
103
104    def connectionLost(self):
105        pass
106
107# Build local module
108from new import module
109m = module('cpushare_buy')
110
111# Create bytecode -- i686 only
112from cpushare.seccomp_gen import seccomp_gen_class
113m.seccomp_gen_hash = {}
114m.seccomp_gen_hash['i686'] = seccomp_gen_class('bytecode', 'i686')
115m.seccomp_gen_hash['i686'].heap_kbytes = 1
116m.seccomp_gen_hash['i686'].stack_kbytes = 1
117
118# Estimate of the max number of seconds that the sell client
119# will take to checkpoint and send its state back to us
120m.checkpoint_sec = 10
121
122# Our buying state machine
123m.buy_state_machine_class = buy_state_machine_class
124
125# Append our module to the global list of modules
126sys.modules['cpushare_buy'] = m
127
128# Build a new command line and run twistd
129sys.argv = [sys.argv[0], '-q', '-n', 'cpushare', '--order', sys.argv[1]]
130from twisted.scripts.twistd import run
131run()
132
Note: See TracBrowser for help on using the repository browser.