cc1  v2.1
CC1 source code docs
 All Classes Namespaces Files Functions Variables Pages
main.py
Go to the documentation of this file.
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # @COPYRIGHT_begin
4 #
5 # Copyright [2010-2014] Institute of Nuclear Physics PAN, Krakow, Poland
6 #
7 # Licensed under the Apache License, Version 2.0 (the "License");
8 # you may not use this file except in compliance with the License.
9 # You may obtain a copy of the License at
10 #
11 # http://www.apache.org/licenses/LICENSE-2.0
12 #
13 # Unless required by applicable law or agreed to in writing, software
14 # distributed under the License is distributed on an "AS IS" BASIS,
15 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
18 #
19 # @COPYRIGHT_end
20 
21 from select import select
22 import json
23 import logging
24 import os
25 import requests
26 import settings
27 import sys
28 import time
29 from threading import Thread
30 import Input
31 
32 APP_PATH = os.path.abspath(os.path.dirname(__file__))
33 
34 # config loggers
35 logger = logging.getLogger(__name__)
36 logger.setLevel(settings.LOG_LEVEL)
37 
38 fh = logging.FileHandler(os.path.join(settings.LOG_DIR, 'vmm.log'))
39 fh.setLevel(settings.LOG_LEVEL)
40 logger.addHandler(fh)
41 
42 ch = logging.StreamHandler(sys.stdout)
43 ch.setLevel(settings.LOG_LEVEL)
44 logger.addHandler(ch)
45 
47 try:
48  dev.find(name="keyboard")
49 except Exception:
50  raise Exception("No such device")
51 print dev
52 logger.info('Setting keyboard to %s bus=0x%x, vendor=0x%x, product=0x%x, version=0x%x' % (dev.name, dev.idbus, dev.idvendor, dev.idproduct, dev.idversion))
53 
54 
55 verify = os.path.isdir(settings.CA_DIR)
56 
57 VERSION = 0
58 actions = None
59 try:
60  actions = __import__('actions')
61  VERSION = actions.VERSION
62 except Exception:
63  pass
64 
65 
66 def rpc(cmd, params=None):
67  logger.debug("RPC: %s, PARAMS: %s" % (cmd, params))
68  global VERSION
69  global actions
70  if params:
71  params['version'] = VERSION
72  else:
73  params = {'version': VERSION}
74  try:
75  r = requests.get('%s/%s' % (settings.CTX_ADDRESS, cmd), verify=verify, params=params)
76  logger.debug('status: %s, ok: %s, text: %s' % (r.status_code, r.ok, r.text))
77  except Exception, e:
78  logger.error('requests error %s' % e)
79  return
80 
81  if not r.ok:
82  return
83 
84  r = json.loads(r.text)
85  if not r:
86  return None
87  if r['status'] != 'ok':
88  logger.error('RPC Error: %s' % r['status'])
89  if 'actions_file' in r:
90  f = file(os.path.join(APP_PATH, 'actions.py'), 'w')
91  f.write(r['actions_file'])
92  f.close()
93  if 'actions' in sys.modules:
94  reload(actions)
95  else:
96 
97  actions = __import__('actions')
98  VERSION = actions.VERSION
99  return r
100 
101 
103  ca_bundle = open('ca_bundle.crt', 'wb')
104 
105  if not os.path.isdir(settings.CA_DIR):
106  logger.info('certificates directory does not exits, every request will be accepted')
107  verify = False
108  return
109  for crt in os.listdir(settings.CA_DIR):
110  f = open(os.path.join(settings.CA_DIR, crt), 'r')
111  ca_bundle.writelines(f.readlines())
112 
113 
114 class HelloCommand(Thread):
115  def run(self):
116  gather_certs()
117  ok = False
118  fails = 10
119  while not ok:
120  try:
121  r = rpc('hello')
122  if r['status'] != 'ok':
123  logger.error('Hello failed, no acceptance from server (err %s), exiting program...' % (r['status']))
124  fails -= 1
125  if fails < 1:
126  exit(1)
127  #exit(1)
128  else:
129  ok = True
130  except Exception, e:
131  logger.error('error while connecting to ctx server (will renew...) %s' % (e))
132  time.sleep(60)
133 
134 
135 class ProcessCommand(Thread):
136  def run(self):
137  logger.info('Start thread')
138  exist = True
139  while exist:
140  try:
141  r = rpc('get_command')
142  if not r or r['status'] != 'ok':
143  exist = False
144  break
145 
146  r = r['data']
147  response = None
148  command_id = r['id']
149  logger.info("Requested command: %s(%s)" % (r['name'], r['args']))
150 
151  if 'name' not in r:
152  error_msg = 'ERROR: No command parameter'
153  logger.error(error_msg)
154  rpc('finish_command', {'status': 'failed', 'command_id': command_id,
155  'error_message': error_msg})
156  try:
157  call_action = getattr(actions, r['name'], None)
158  if not call_action:
159  rpc('finish_command', {'status': 'failed', 'command_id': command_id,
160  'error_message': 'Invalid action'})
161  if r['args']:
162  args = json.loads(r['args'])
163  else:
164  args = {}
165  response = call_action(**args)
166  logger.info("response: %s" % str(response))
167  rpc('finish_command', dict({'status': 'finished', 'command_id': command_id, 'returns': response}))
168  except Exception, e:
169  error_msg = 'ERROR: UNDEFINED ERROR %s' % unicode(e)
170  logger.exception(error_msg)
171  rpc('finish_command', {'status': 'failed', 'command_id': command_id,
172  'error_message': error_msg})
173  except Exception, e:
174  logger.exception('General exception: %s' % e)
175  exist = False
176 
178 t.start()
179 # check if commands are in CM
180 t = ProcessCommand()
181 t.start()
182 
183 logger.info('Waiting for keyboard')
184 while True:
185  r, w, x = select([dev], [], [])
186  for event in dev.readall():
187  if event.code == 113 and event.value == 1:
188  logger.info("Key received")
189  t = ProcessCommand()
190  t.start()
191