#! /usr/bin/python import rascsi_interface_pb2 as proto import socket import socket_cmds import time from struct import pack, unpack from yapsy.PluginManager import PluginManager ######################### def send_pb_command(payload, host='localhost', port=6868): """ Takes a (str) containing a serialized protobuf as argument. Establishes a socket connection with RaSCSI. """ counter = 0 tries = 20 error_msg = "" import socket while counter < tries: try: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) return socket_cmds.send_over_socket(sock, payload) except socket.error as error: counter += 1 logging.warning("The RaSCSI service is not responding - attempt %s/%s", str(counter), str(tries)) error_msg = str(error) sleep(0.2) logging.error(error_msg) # After failing all attempts, throw a 404 error abort(404, _( u"The RaSCSI Web Interface failed to connect to RaSCSI at %(host)s:%(port)s " u"with error: %(error_msg)s. The RaSCSI process is not running or may have crashed.", host=host, port=port, error_msg=error_msg, ) ) ######################### def get_image_files_info(host='localhost',port=6868): """ Sends a DEFAULT_IMAGE_FILES_INFO command to the server. Returns a dict with: - (bool) status - (str) images_dir, path to images dir - (list) of (str) image_files - (int) scan_depth, the current scan depth """ command = proto.PbCommand() command.operation = proto.PbOperation.DEFAULT_IMAGE_FILES_INFO data = send_pb_command(command.SerializeToString(),host,port) result = proto.PbResult() result.ParseFromString(data) images_dir = result.image_files_info.default_image_folder image_files = result.image_files_info.image_files scan_depth = result.image_files_info.depth return { "status": result.status, "images_dir": images_dir, "image_files": image_files, "scan_depth": scan_depth, } ######################### def socket_read_n(conn, n): """ Read exactly n bytes from the socket. Raise RuntimeError if the connection closed before n bytes were read. """ buf = bytearray(b'') while n > 0: data = conn.recv(n) if data == '': raise RuntimeError('unexpected connection close') buf.extend(data) n -= len(data) return bytes(buf) ######################### def deserialize_message(conn, message): # read the header with the size of the protobuf data buf = socket_read_n(conn, 4) size = (int(buf[3]) << 24) + (int(buf[2]) << 16) + (int(buf[1]) << 8) + int(buf[0]) buf = socket_read_n(conn, size) message.ParseFromString(buf) ######################### def serialize_message(conn, data): conn.sendall(pack("