You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

126 lines
3.9 KiB

  1. #! /usr/bin/python
  2. import os, struct, sys, random
  3. import gd
  4. from cpushare.proto_const import *
  5. from cpushare.exceptions import CompilationError
  6. # Our input data
  7. source = False
  8. result = False
  9. todo = 0
  10. # Parse command line
  11. if len(sys.argv) < 4:
  12. print 'Usage: %s <buy_order.cpu> -<mode> [image list]' % (sys.argv[0],)
  13. sys.exit(-1)
  14. mode = sys.argv[2][1]
  15. source = sys.argv[3:]
  16. result = [False] * len(source)
  17. class buy_state_machine_class(object):
  18. buy_api = '0.0.0'
  19. w, h = 0, 0
  20. index = -1
  21. answer = ''
  22. def __init__(self, protocol):
  23. self.protocol = protocol
  24. self.handler = self.stringReceived
  25. def start(self):
  26. global todo, source
  27. if todo >= len(source):
  28. return # We're finished... FIXME: a process is stuck
  29. self.index = todo
  30. todo += 1
  31. gd.gdMaxColors = 256 * 256 * 256
  32. im = gd.image(source[self.index])
  33. # Send mode
  34. self.protocol.sendString(PROTO_SECCOMP_FORWARD + mode)
  35. # Send image size
  36. (self.w, self.h) = (w, h) = im.size()
  37. print 'sending %s (%dx%d)' % (source[self.index], w, h)
  38. msg = chr(w / 256) + chr(w % 256) + chr(h / 256) + chr(h % 256)
  39. self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
  40. # Send image contents
  41. msg = ''
  42. for y in range(h):
  43. for x in range(w):
  44. p = im.getPixel((x, y))
  45. rgb = im.colorComponents(p)
  46. msg += chr(rgb[1]) # use green coordinate
  47. self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
  48. print '%s bytes sent' % len(msg)
  49. def stringReceived(self, string):
  50. control = string[0]
  51. data = string[1:]
  52. if control == PROTO_SECCOMP_FORWARD:
  53. self.answer += data
  54. if ord(self.answer[-1]) != 0:
  55. return
  56. global result
  57. result[self.index] = self.answer[:-1]
  58. print self.answer[:-1],
  59. self.protocol.sendString(PROTO_SECCOMP_SUCCESS)
  60. # the PROTO_SECCOMP_SUCCESS probably won't have a chance
  61. # to go out but it doesn't matter because we'll disconnect
  62. # not just this but all other seccomp state machines too
  63. from twisted.internet import reactor
  64. reactor.stop()
  65. elif control == PROTO_SECCOMP_SIGNAL:
  66. print 'Checkpoint starting'
  67. elif control == PROTO_LOG:
  68. print repr(data)
  69. else:
  70. if control == PROTO_SECCOMP_SUCCESS:
  71. pass
  72. elif control == PROTO_SECCOMP_FAILURE:
  73. status = struct.unpack('!i', data)[0]
  74. exit_code = status >> 8
  75. signal = status & 0xff
  76. s = 'Seccomp failure: status %d, exit_code %d, signal %d.' % \
  77. (status, exit_code, signal)
  78. print s
  79. else:
  80. s = 'Unknown failure %d - %s' % (ord(control), repr(string))
  81. self.protocol.sendString(PROTO_SECCOMP_FAILURE + s)
  82. print s
  83. self.protocol.sendString(PROTO_SECCOMP_FAILURE)
  84. self.protocol.transport.loseConnection()
  85. def connectionLost(self):
  86. pass
  87. # Build local module
  88. from new import module
  89. m = module('cpushare_buy')
  90. # Create bytecode -- i686 only
  91. from cpushare.seccomp_gen import seccomp_gen_class
  92. m.seccomp_gen_hash = {}
  93. m.seccomp_gen_hash['i686'] = seccomp_gen_class('bytecode', 'i686')
  94. m.seccomp_gen_hash['i686'].heap_kbytes = 1
  95. m.seccomp_gen_hash['i686'].stack_kbytes = 1
  96. # Estimate of the max number of seconds that the sell client
  97. # will take to checkpoint and send its state back to us
  98. m.checkpoint_sec = 10
  99. # Our buying state machine
  100. m.buy_state_machine_class = buy_state_machine_class
  101. # Append our module to the global list of modules
  102. sys.modules['cpushare_buy'] = m
  103. # Build a new command line and run twistd
  104. sys.argv = [sys.argv[0], '-q', '-n', 'cpushare', '--order', sys.argv[1]]
  105. from twisted.scripts.twistd import run
  106. run()