def mapleDeployment(host, loacalMaple, loaclMapleHandler, loaclMapleDataMerger, loaclGetDestination): # create the deployment mach = SshMachine(host, user="******", keyfile="/home/zitongc2/.ssh/id_rsa") server = DeployedServer(mach) # and now you can connect to it the usual way conn = server.classic_connect() print("[INFO] Connected to ", host) conn._config['sync_request_timeout'] = None def getResult(string): print(string) remoteMaple = conn.teleport(loacalMaple) remoteMapleHandler = teleport_function(conn, loaclMapleHandler) remoteMapleHandler(remoteMaple, "/home/zitongc2/test/phase0/input", getResult) # print("[INFO] Done processing, now sendind result to desinated location") remoteMapleDataMerger = teleport_function(conn, loaclMapleDataMerger) remoteMapleDataMerger(loaclGetDestination) # when you're done - close the server and everything will disappear print("[INFO] done") server.close()
def test_smtp_login_expect_reject(self): message = EmailMessage() message["From"] = "*****@*****.**" message["To"] = "*****@*****.**" message["Subject"] = "Test" machine: pb.SshMachine = pb.SshMachine(host="remote.example.com", user="******", keyfile="~/.ssh/id_rsa") server = DeployedServer(machine) connection: rpyc.Connection = server.classic_connect() with connection.modules.smtplib.SMTP("mail.example.com") as smtp: with self.assertRaises(smtplib.SMTPNotSupportedError) as e: smtp.login(user="******", password="******") smtp.send_message(message, from_addr="*****@*****.**", to_addrs="*****@*****.**") self.assertIn("SMTP AUTH extension not supported by server", str(e.exception), msg=str(e.exception)) connection.close() server.close() machine.close()
def test_login_mailaddress_starttls_wrong_credentials_expect_rejected( self): message = EmailMessage() message["From"] = "*****@*****.**" message["To"] = "*****@*****.**" message["Subject"] = "Test" machine: pb.SshMachine = pb.SshMachine(host="remote.example.com", user="******", keyfile="~/.ssh/id_rsa") server = DeployedServer(machine) connection: rpyc.Connection = server.classic_connect() with connection.modules.smtplib.SMTP("mail.example.com", 587) as smtp: smtp.starttls() with self.assertRaises(smtplib.SMTPAuthenticationError) as e: smtp.login(user="******", password="******") self.assertIn("Error: authentication failed", str(e.exception), msg=str(e.exception)) connection.close() server.close() machine.close()
def __init__(self, hostname: str, username: Optional[str] = None, password: Optional[str] = None) -> None: """Connects (or start with SSH if needed) to RPyC remote SlaveService. Connect to RPyC SlaveService on remote machine. If the service isn't running, try to deploy it with SSHConnection and RPyC zero deploy library. Args: hostname: The hostname of the component we want to connect to. username: Username for SSH login (if needed). password: Password for SSH login (if needed). """ self._server = None try: # Checks if the machine already runs RPyC SlaveService. self._connection = rpyc.classic.connect(hostname, keepalive=True) except ConnectionRefusedError: if username is None or password is None: # Not given necessary SSH credentials. raise with SSHConnection(hostname, username, password) as ssh: # Upload RPyC and start SlaveService in a temporarily directory. self._server = DeployedServer(ssh.shell) # pylint: disable=no-member self._connection = self._server.classic_connect()
def __init__(self, host=None, user=None, port=None, keyfile=None, password=None, python_executable='python', ssh_opts=[], hop=None, hop_user=None, hop_port=None, hop_keyfile=None, hop_password=None, hop_python_executable='python'): """mdsConnector constructor. Specify host to connect to a remote host via ssh or omit host or specify None to use local MDSplus objects. Specify the full path of the python executable on the remote host if python is not in the default path""" if host is None: self.local = True import MDSplus self.mdsplus = MDSplus self.connection = None else: if python_executable == 'python': import sys if sys.version_info[0] == 3: python_executable = 'python3' self.local = False self.mach = SshMachine(host, user=user, port=port, keyfile=keyfile, password=password, ssh_opts=ssh_opts) self.server = DeployedServer(self.mach, python_executable=python_executable) self.connection = self.server.classic_connect() if hop is None: self.mdsplus = self.connection.modules['MDSplus'] try: self.dill = self.connection.modules['dill'] except: self.dill = None else: self.hop_connection = self.connection.modules[ 'mdsconnector'].mdsConnector( hop, user=hop_user, port=hop_port, keyfile=hop_keyfile, password=hop_password, python_executable=hop_python_executable) self.mdsplus = self.hop_connection.mdsplus
class SshHost(BaseHost): def __init__(self, **kwargs): BaseHost.__init__(self, **kwargs) self._mach = None self.deployment = None def connect(self): if self.deployment is None: self._mach = SshMachine(**self.kwargs) self.deployment = DeployedServer(self._mach) return self.deployment.classic_connect() def close(self): if self.deployment is not None: self.deployment.close() self._mach.close()
def __init__(self, machine='localhost', username=None, ssh_key_fname=None, python_executable=None, environ=None, extra_paths=None): self.conn = None self.sshctx = None self.processing_server = None self.handler = None self.last_threat_level = 0.0 self.last_prediction = "Nothing" print 'Client: Connect to %s:%s' % (username, machine) self.is_dummy = not os.path.isfile( '/home/sven2/python/ghack/alexnet.caffemodel') if not self.is_dummy: self.sshctx = SshMachine(machine, user=username, keyfile=ssh_key_fname) self.server = DeployedServer(self.sshctx, python_executable=python_executable) self.conn = self.server.classic_connect() self.temp_dir = self.server.remote_machine.tempdir().__enter__() if environ is not None: for k, v in environ.iteritems(): if k in self.conn.modules.os.environ: self.conn.modules.os.environ[k] += ':' + v else: self.conn.modules.os.environ[k] = v if extra_paths is not None: for p in extra_paths: self.conn.modules.sys.path.append(p) self.Assoc = self.conn.modules.ghack.assoc_server.AssocServer self.assoc_server = self.Assoc() self.last_prediction = None self.conn.modules.sys.stdout = sys.stdout #open('/tmp/procout.txt', 'wt') self.conn.modules.sys.stderr = sys.stdout #open('/tmp/procout.err', 'wt') # Current state self.commands = [] self.has_updated_prediction = False # Prepare asynchronous function calls self.thread_event = threading.Event() self.done = False if not self.is_dummy: self.thread = threading.Thread(target=self.workerThread) self.thread.start()
def __init__(self, ip_info, modules, username=None, password=None, strict_host_key_checking=True): """ Initializes the context """ self.ips = [] if isinstance(ip_info, basestring): self.ips = [ip_info] elif isinstance(ip_info, list): self.ips = ip_info else: raise ValueError( 'IP info needs to be a single IP or a list of IPs') if not isinstance(modules, list) and not isinstance( modules, set) and not isinstance(modules, tuple): raise ValueError('Modules should be a list, set or tuple') self.username = username if username is not None else check_output( 'whoami').strip() ssh_opts = [] if strict_host_key_checking is False: ssh_opts.append('-o StrictHostKeyChecking=no') self.machines = [ SshMachine(ip, user=self.username, password=password, ssh_opts=tuple(ssh_opts)) for ip in self.ips ] self.servers = [DeployedServer(machine) for machine in self.machines] self.modules = modules
class RPyCConnection(BaseConnection): """RPyC wrapper for component connection. In case the machine doesn't already run SlaveService, we will try to use SSH to upload and deploy RPyC SlaveService. """ def __init__(self, hostname: str, username: Optional[str] = None, password: Optional[str] = None) -> None: """Connects (or start with SSH if needed) to RPyC remote SlaveService. Connect to RPyC SlaveService on remote machine. If the service isn't running, try to deploy it with SSHConnection and RPyC zero deploy library. Args: hostname: The hostname of the component we want to connect to. username: Username for SSH login (if needed). password: Password for SSH login (if needed). """ self._server = None try: # Checks if the machine already runs RPyC SlaveService. self._connection = rpyc.classic.connect(hostname, keepalive=True) except ConnectionRefusedError: if username is None or password is None: # Not given necessary SSH credentials. raise with SSHConnection(hostname, username, password) as ssh: # Upload RPyC and start SlaveService in a temporarily directory. self._server = DeployedServer(ssh.shell) # pylint: disable=no-member self._connection = self._server.classic_connect() @property def rpyc(self) -> rpyc.Connection: """The RPyc connection to component.""" return self._connection def close(self) -> None: """Closes RPyC connections.""" self._connection.close() if self._server is not None: self._server.close()
def establish_connection(self, node, user): """ Establishes connection from localhost to node via SshMachine and zerodeploy. The connection is authenticated and hence secure. Populates the connection in a dict called connection_handles. This function does not take care of timeouts. Timeouts need to be handled by the calling function Returns True on success and False otherwise """ try: rem = SshMachine(node, user) dep = DeployedServer(rem) conn = dep.classic_connect() self.connection_handles[node][user] = (rem, dep, conn) self.subp_conn[node][user] = conn.modules.subprocess except: return False return True
def test_login_username_smtps_expect_pass(self): message = EmailMessage() message["From"] = "*****@*****.**" message["To"] = "*****@*****.**" message["Subject"] = "Test" machine: pb.SshMachine = pb.SshMachine(host="remote.example.com", user="******", keyfile="~/.ssh/id_rsa") server = DeployedServer(machine) connection: rpyc.Connection = server.classic_connect() with connection.modules.smtplib.SMTP_SSL("mail.example.com", 465) as smtp: smtp.login(user="******", password="******") connection.close() server.close() machine.close()
def go(): creds = getCreds() print("Connecting...") mach = ParamikoMachine(creds['remote address'], user=creds['remote user'], keyfile=creds['remote key'], missing_host_policy=ignoreIt()) print("Deploying RPC interface...") server = DeployedServer(mach) print("Connected.") conn = server.classic_connect() import webFunctions webFunctions.urllib.request = conn.modules['urllib.request'] wg = webFunctions.WebGetRobust() print(wg.getpage('http://api.ipify.org?format=json')) import ScrapePlugins.H.SadPandaLoader.Run ScrapePlugins.H.SadPandaLoader.Run.test()
def connect(self): """Initiate ssh tunnel & rpyc server""" self.logger.info('Opening connection @%s'%self.ip) try: with RLock(): self.nxTunnel = SshMachine(self.ip,self.user) self.nxServer = DeployedServer(self.nxTunnel) self.nxConnA = self.nxServer.classic_connect() self.nxConnB = self.nxServer.classic_connect() except Exception: self.logger.error('Failed opening @%s' % self.ip) self.logger.info('Successfully connected @%s'%self.ip)
def get_rpyc(self, venvpath=None, pythonpath=None, ssh=None): """Return a new ``rpyc`` classic connection to the Python interpreter found at ``pythonpath`` or the virtualenv at ``venvpath``. """ # last place we look is for a class attr venvpath = venvpath or self.location.facts.get( 'venvpath', getattr(self, 'venvpath', None)) if venvpath and pythonpath is None: pythonpath = self.ssh.path(venvpath).join('bin/python/') ssh = ssh or self.ssh server = self._ssh2zdservers.get(ssh) if not server: server = DeployedServer(ssh, python_executable=pythonpath) self._ssh2zdservers[ssh] = server conn = server.classic_connect() # need this ref otherwise the server will tear down conn._zero_deploy_server = server return conn
def create_remote_node(self, hostname, username, keyfile, ntype, addr, config=None): if config is None: config = {} remote_machine = SshMachine(host=hostname, user=username, keyfile=keyfile) remote_server = DeployedServer(remote_machine) conn = remote_server.classic_connect() site = conn.modules.site python_pkg_path = site.getsitepackages()[0] # if `asgrids` wasn't available remotely, now we installed it # but we need to reconnect to get an updated conn.modules # TODO Might not be needed if using execute/eval if not self.check_remote(remote_server, python_pkg_path): remote_server.close() remote_server = DeployedServer(remote_machine) self.remote_machines.append(remote_machine) self.remote_servers.append(remote_server) conn = remote_server.classic_connect() serving_thread = BgServingThread(conn) self.server_threads.append(serving_thread) self.conns[addr] = conn # Using execute/eval allows working on a remote single namespace # useful when teleporting functions that need using remote object names # as using conn.modules create a locate but not a remote namespace member if ntype is 'load': conn.execute("from asgrids import NetworkLoad") conn.execute("node=NetworkLoad()") conn.execute("node.local='{}'".format(addr)) node = conn.namespace['node'] elif ntype is 'allocator': conn.execute("from asgrids import NetworkAllocator") conn.execute("node=NetworkAllocator()") node = conn.namespace['node'] else: raise ValueError("Can't handle ntype == {}".format(ntype)) self.nodes[addr] = node # Return node netref object and rpyc connection return node, conn
def juiceDeployment(host, loacalJuice, loaclJuiceHandler, localJuiceDataMerger): # create the deployment mach = SshMachine(host, user="******", keyfile="/home/zitongc2/.ssh/id_rsa") server = DeployedServer(mach) # and now you can connect to it the usual way conn = server.classic_connect() print("[INFO] Connected to ", host) conn._config['sync_request_timeout'] = None remoteJuice = conn.teleport(loacalJuice) remoteMapleHandler = teleport_function(conn, loaclJuiceHandler) remoteMapleHandler(remoteJuice) print("[INFO] Done processing, now sendind result to desinated location") remoteJuiceDataMerger = teleport_function(conn, localJuiceDataMerger) remoteJuiceDataMerger(socket.gethostbyname(socket.gethostname())) # when you're done - close the server and everything will disappear server.close()
def establish_connection(self, node, user): """ Establishes rpyc connection from localhost to node via SshMachine and zerodeploy. The connection is authenticated and hence secure. Populates the connection in a dict called connection_handles. This function does not take care of timeouts. Timeouts need to be handled by the calling function Returns True on success and False otherwise """ keyfile = None if 'ssh_keyfile' in self.global_config: keyfile = self.global_config['ssh_keyfile'] try: self.connection_handles[node] = {} self.subp_conn[node] = {} rem = SshMachine(node, user, keyfile=keyfile) dep = DeployedServer(rem) conn = dep.classic_connect() self.connection_handles[node][user] = (rem, dep, conn) self.subp_conn[node][user] = conn.modules.subprocess except: return False return True
def test_logged_out_starttls_expect_client_host_rejected(self): message = EmailMessage() message["From"] = "*****@*****.**" message["To"] = "*****@*****.**" message["Subject"] = "Test" machine: pb.SshMachine = pb.SshMachine(host="remote.example.com", user="******", keyfile="~/.ssh/id_rsa") server = DeployedServer(machine) connection: rpyc.Connection = server.classic_connect() with connection.modules.smtplib.SMTP("mail.example.com", 587) as smtp: smtp.starttls() with self.assertRaises(smtplib.SMTPRecipientsRefused) as e: smtp.send_message(message, from_addr="*****@*****.**", to_addrs="*****@*****.**") self.assertIn("Client host rejected: Access denied", str(e.exception)) connection.close() server.close() machine.close()
def test_deploy(self): rem = SshMachine("localhost") SshMachine.python = rem[sys.executable] with DeployedServer(rem) as dep: conn = dep.classic_connect() print(conn.modules.sys) func = conn.modules.os.getcwd print(func()) try: func() except EOFError: pass else: self.fail("expected an EOFError")
def go(): creds = getCreds() print("Connecting...") mach = ParamikoMachine(creds['remote address'], user=creds['remote user'], keyfile=creds['remote key'], missing_host_policy=ignoreIt()) print("Deploying RPC interface...") server = DeployedServer(mach) print("Connected.") conn = server.classic_connect() import webFunctions webFunctions.urllib.request = conn.modules['urllib.request'] wg = webFunctions.WebGetRobust() print(wg.getpage('http://api.ipify.org?format=json')) import ScrapePlugins.SadPandaLoader.Run ScrapePlugins.SadPandaLoader.Run.test()
def test_deploy_paramiko(self): rem = ParamikoMachine("localhost", missing_host_policy=paramiko.AutoAddPolicy()) with DeployedServer(rem) as dep: conn = dep.classic_connect() print(conn.modules.sys) func = conn.modules.os.getcwd print(func()) try: func() except EOFError: pass else: self.fail("expected an EOFError")
def test_deploy_paramiko(self): try: import paramiko # @UnusedImport except Exception: self.skipTest("Paramiko is not available") from plumbum.machines.paramiko_machine import ParamikoMachine rem = ParamikoMachine("localhost", missing_host_policy = paramiko.AutoAddPolicy()) with DeployedServer(rem) as dep: conn = dep.classic_connect() print (conn.modules.sys) func = conn.modules.os.getcwd print (func()) try: func() except EOFError: pass else: self.fail("expected an EOFError")
class SshDriver(object): def __init__(self, host): self.host = host self.machine = SshMachine(self.host) self.rpyc_serv = DeployedServer(self.machine) self.rpyc_conn = self.rpyc_serv.classic_connect() self.rpyc_conn.ping() def upload(self, local_path, remote_path): self.machine.upload(local_path, remote_path) def download(self, remote_path, local_path): self.machine.download(remote_path, local_path) def calculate_checksum(self, filename): return calculate_checksum(filename, self.rpyc_conn) def isfile(self, filename): return self.rpyc_conn.modules.os.path.isfile(filename) def ensure_directory(self, path): ensure_directory(path, self.rpyc_conn) def ensure_parent_directory(self, filename): parent_directory = os.path.dirname(filename) self.ensure_directory(parent_directory) def list_all_files(self, path): return list_all_files(path, self.rpyc_conn) def list_directories(self, path): return list_directories(path, self.rpyc_conn) def remove_file(self, filename): self.rpyc_conn.modules.os.remove(filename) def file_size(self, filename): return self.rpyc_conn.modules.os.path.getsize(filename) def sort_file_entries_by_size(self, file_entries): return sorted(file_entries, key=lambda file_entry: self.file_size(file_entry[0]))
def __init__(self, machine='localhost', username=None, ssh_key_fname=None, python_executable=None, environ=None, extra_paths=None): self.conn = None self.sshctx = None self.processing_server = None self.handler = None self.last_threat_level = 0.0 self.last_prediction = "Nothing" print 'Client: Connect to %s:%s' % (username, machine) self.is_dummy = not os.path.isfile('/home/sven2/python/ghack/alexnet.caffemodel') if not self.is_dummy: self.sshctx = SshMachine(machine, user=username, keyfile=ssh_key_fname) self.server = DeployedServer(self.sshctx, python_executable=python_executable) self.conn = self.server.classic_connect() self.temp_dir = self.server.remote_machine.tempdir().__enter__() if environ is not None: for k, v in environ.iteritems(): if k in self.conn.modules.os.environ: self.conn.modules.os.environ[k] += ':' + v else: self.conn.modules.os.environ[k] = v if extra_paths is not None: for p in extra_paths: self.conn.modules.sys.path.append(p) self.Assoc = self.conn.modules.ghack.assoc_server.AssocServer self.assoc_server = self.Assoc() self.last_prediction = None self.conn.modules.sys.stdout = sys.stdout #open('/tmp/procout.txt', 'wt') self.conn.modules.sys.stderr = sys.stdout #open('/tmp/procout.err', 'wt') # Current state self.commands = [] self.has_updated_prediction = False # Prepare asynchronous function calls self.thread_event = threading.Event() self.done = False if not self.is_dummy: self.thread = threading.Thread(target=self.workerThread) self.thread.start()
def _rpyc_get_deployed_server(cls, name, ssh_connection=None): """Create and cache a deployed server object. Args: name (str): The name for the deployed server cache. ssh_connection (obj): An ssh_connection object. Returns: A new or cached deployed_server object. """ cls.log.debug("getting deployed server") if name not in cls._deployed_servers: deployed_server = DeployedServer(ssh_connection) cls._deployed_servers[name] = deployed_server cls.log.debug("cached deployed server %s" % name) else: cls.log.debug("getting deployed server %s from cache" % name) deployed_server = cls._deployed_servers[name] if deployed_server: return deployed_server return None
class AssocClient: # Init connection to remote processing server in ctor def __init__(self, machine='localhost', username=None, ssh_key_fname=None, python_executable=None, environ=None, extra_paths=None): self.conn = None self.sshctx = None self.processing_server = None self.handler = None self.last_threat_level = 0.0 self.last_prediction = "Nothing" print 'Client: Connect to %s:%s' % (username, machine) self.is_dummy = not os.path.isfile( '/home/sven2/python/ghack/alexnet.caffemodel') if not self.is_dummy: self.sshctx = SshMachine(machine, user=username, keyfile=ssh_key_fname) self.server = DeployedServer(self.sshctx, python_executable=python_executable) self.conn = self.server.classic_connect() self.temp_dir = self.server.remote_machine.tempdir().__enter__() if environ is not None: for k, v in environ.iteritems(): if k in self.conn.modules.os.environ: self.conn.modules.os.environ[k] += ':' + v else: self.conn.modules.os.environ[k] = v if extra_paths is not None: for p in extra_paths: self.conn.modules.sys.path.append(p) self.Assoc = self.conn.modules.ghack.assoc_server.AssocServer self.assoc_server = self.Assoc() self.last_prediction = None self.conn.modules.sys.stdout = sys.stdout #open('/tmp/procout.txt', 'wt') self.conn.modules.sys.stderr = sys.stdout #open('/tmp/procout.err', 'wt') # Current state self.commands = [] self.has_updated_prediction = False # Prepare asynchronous function calls self.thread_event = threading.Event() self.done = False if not self.is_dummy: self.thread = threading.Thread(target=self.workerThread) self.thread.start() def workerThread(self): # Executes dreaming communication in a background thread try: while not self.done: while len(self.commands): cmd = self.commands[0] print 'Client: Execute command %s...' % cmd[0] if cmd[0] == 'loadModel': self.assoc_server.loadModel() elif cmd[0] == 'setCamImage': self.last_image = cmd[1] serialized_image = pickle.dumps(self.last_image, protocol=0) self.assoc_server.setCamImageSerialized( serialized_image) elif cmd[0] == 'setCamImageByLocalFilename': self.assoc_server.setCamImageByLocalFilename(cmd[1]) elif cmd[0] == 'setCamImageByFileContents': self.assoc_server.setCamImageByFileContents(cmd[1]) elif cmd[0] == 'process': self.assoc_server.processImage() self.last_prediction = self.assoc_server.getPredictions( ) self.last_threat_level = self.assoc_server.getThreatLevel( ) self.has_updated_prediction = True self.commands.pop(0) print 'Client: Command %s done' % cmd[0] if self.done: break print 'Client: Sleeping...' self.thread_event.wait() self.thread_event.clear() finally: self.commands = [] self.done = True def loadModel(self): self.commands.append(['loadModel']) self.thread_event.set() def setCamImage(self, img): self.commands.append(['setCamImage', img.copy()]) self.thread_event.set() def setCamImageByLocalFilename(self, img_fn): self.commands.append(['setCamImageByLocalFilename', img_fn]) self.thread_event.set() def setCamImageByFileContents(self, file_contents): self.commands.append(['setCamImageByFileContents', file_contents]) self.thread_event.set() def process(self): self.commands.append(['process']) self.thread_event.set() def hasUpdatedPrediction(self): if self.is_dummy: return True return self.has_updated_prediction def isQueueEmpty(self): return len(self.commands) == 0 def getPrediction(self): self.has_updated_prediction = False return self.last_prediction def getThreatLevel(self): self.has_updated_prediction = False return self.last_threat_level def quit(self): self.done = True self.thread_event.set() def __del__(self): self.done = True self.thread_event.set() if not self.conn is None: print 'Client: Disconnect' del self.conn self.conn = None
class Controller: """ Stores connection variables and perfoms monitoring and data syncing functions """ def __init__(self, username, ipaddress): # Connection Parameters self.user = username self.ip = ipaddress # Connection Resources self.nxTunnel = None self.nxServer = None self.nxConnA = None self.nxConnB = None self.rest = vellosREST(ipaddress) # Extend logger of parent script importing this module self.logger = logging.getLogger('vBrokerLog.controller.Controller') # Resources local to controller self.pdb = '/var/lib/pdb/pdb-rest.db' # Flag when monitored proc/s or system has failed self.has_failed = Event() def __enter__(self): self.connect() def __exit__(self, exc_type, exc_value, traceback): self.close() def to_dict(self): """Return dict of crucial attributes""" controller_dict = { 'user_name' : self.user, 'ip_address': self.ip } return controller_dict def _execute(self, cmd): """Execute shell command """ try: if self.is_connected(): self.nxConnA.modules.subprocess.check_call(cmd) else: return False except subprocess.CalledProcessError: return False return True def connect(self): """Initiate ssh tunnel & rpyc server""" self.logger.info('Opening connection @%s'%self.ip) try: with RLock(): self.nxTunnel = SshMachine(self.ip,self.user) self.nxServer = DeployedServer(self.nxTunnel) self.nxConnA = self.nxServer.classic_connect() self.nxConnB = self.nxServer.classic_connect() except Exception: self.logger.error('Failed opening @%s' % self.ip) self.logger.info('Successfully connected @%s'%self.ip) def close(self): """Close ssh tunnel % destroy rpyc server""" self.logger.info('Closing connection @%s'%self.ip) try: self.nxServer.close() except Exception as e: self.logger.error('Failed closing @%s - %s'%(self.ip,e)) def is_connected(self): """Test if ssh tunnel & rpyc connection is active""" try: with RLock(): self.nxConnA.ping() #self.nxConnB.ping() except: return False return True def ping(self): """Ping controller""" cmd = ['ping','-c','1',self.ip] try: self.logger.info('Pinging @%s'%self.ip) with open(os.devnull, 'w') as devnull: subprocess.check_call(cmd,stdout=devnull) except: self.logger.error('Failed to ping @%s'%self.ip) return False return True def assert_connection(self): """Monitor connection, attempt reconnect if down""" if not self.is_connected(): self.logger.error('lost connection @%s'%self.ip) if self.ping(): self.logger.info('ping @%s succeeded'% self.ip) try: if not self.is_connected(): self.logger.debug('still not connected') self.close() self.connect() self.logger.debug('connection found') self.control_plane_down() except: with RLock(): self.has_failed.set() return False self.logger.error('reconnect @%s fail'% self.ip) else: with RLock(): self.has_failed.set() return False else: return True def monitor(self, procs, interval, kill_monitor): """Monitor processes and exit if failure""" watch = Watch( self, procs, interval, kill_monitor, self.has_failed ) watch.run() def sync(self, dst, event): """Sync pdb-rest.db to to local target""" pdbsync = Sync( self, dst, event) pdbsync.run() def restore(self, nodes, flows): """Install data using REST, ignore if error""" self.logger.info('Restoring nodes @%s'%self.ip) for node_id, node in nodes.iteritems(): snode = json.dumps(node) try: self.logger.debug('Installing node: %s'%snode) self.rest.putNode(node_id, snode) except Exception as e: self.logger.debug('%s - %s'%(node_id,e)) pass self.logger.info('Restoring flows @%s'%self.ip) for flow_id, flow in flows.iteritems(): sflow = json.dumps(flow) try: self.logger.debug('Installing flow: %s'%sflow) self.rest.putFlow(flow_id, json.dumps(flow)) except Exception as e: self.logger.error('%s - %s'%(flow_id,e)) pass return True def remove(self, nodes, flows): """Remove data using REST, ignore if error""" self.logger.info('Removing data @%s'%self.ip) for flow_id, flow in flows.iteritems(): sflow = json.dumps(flow) try: self.logger.debug('Removing flow: %s'%sflow) self.rest.deleteFlow(flow_id) except Exception as e: self.logger.error('%s - %s'%(flow_id,e)) pass for node_id, node in nodes.iteritems(): snode = json.dumps(node) try: self.logger.debug('Removing node: %s'%snode) self.rest.deleteNode(node_id) except Exception as e: self.logger.error('%s - %s'%(node_id,e)) pass return True def diff_switches(self, switches): """Diff passed in switches with ones in inventory""" self.logger.info('Diffing Switches @%s'%self.ip) try: active_switches = self.rest.getSwitchNames()['items'] except Exception as e: self.logger.error('Could not get switches: %s'%e) return set(switches) <= set(active_switches) def control_plane_up(self): """Bring control plane interface up""" self.logger.info('Bringing up br0 @%s'%self.ip) up_cmd = ['/sbin/ifconfig', 'br0', 'up'] return self._execute(up_cmd) def control_plane_down(self): """Bring control plane interface down""" self.logger.info('Bringing down br0 @%s'%self.ip) down_cmd = ['/sbin/ifconfig', 'br0', 'down'] return self._execute(down_cmd)
class AssocClient: # Init connection to remote processing server in ctor def __init__(self, machine='localhost', username=None, ssh_key_fname=None, python_executable=None, environ=None, extra_paths=None): self.conn = None self.sshctx = None self.processing_server = None self.handler = None self.last_threat_level = 0.0 self.last_prediction = "Nothing" print 'Client: Connect to %s:%s' % (username, machine) self.is_dummy = not os.path.isfile('/home/sven2/python/ghack/alexnet.caffemodel') if not self.is_dummy: self.sshctx = SshMachine(machine, user=username, keyfile=ssh_key_fname) self.server = DeployedServer(self.sshctx, python_executable=python_executable) self.conn = self.server.classic_connect() self.temp_dir = self.server.remote_machine.tempdir().__enter__() if environ is not None: for k, v in environ.iteritems(): if k in self.conn.modules.os.environ: self.conn.modules.os.environ[k] += ':' + v else: self.conn.modules.os.environ[k] = v if extra_paths is not None: for p in extra_paths: self.conn.modules.sys.path.append(p) self.Assoc = self.conn.modules.ghack.assoc_server.AssocServer self.assoc_server = self.Assoc() self.last_prediction = None self.conn.modules.sys.stdout = sys.stdout #open('/tmp/procout.txt', 'wt') self.conn.modules.sys.stderr = sys.stdout #open('/tmp/procout.err', 'wt') # Current state self.commands = [] self.has_updated_prediction = False # Prepare asynchronous function calls self.thread_event = threading.Event() self.done = False if not self.is_dummy: self.thread = threading.Thread(target=self.workerThread) self.thread.start() def workerThread(self): # Executes dreaming communication in a background thread try: while not self.done: while len(self.commands): cmd = self.commands[0] print 'Client: Execute command %s...' % cmd[0] if cmd[0] == 'loadModel': self.assoc_server.loadModel() elif cmd[0] == 'setCamImage': self.last_image = cmd[1] serialized_image = pickle.dumps(self.last_image, protocol=0) self.assoc_server.setCamImageSerialized(serialized_image) elif cmd[0] == 'setCamImageByLocalFilename': self.assoc_server.setCamImageByLocalFilename(cmd[1]) elif cmd[0] == 'setCamImageByFileContents': self.assoc_server.setCamImageByFileContents(cmd[1]) elif cmd[0] == 'process': self.assoc_server.processImage() self.last_prediction = self.assoc_server.getPredictions() self.last_threat_level = self.assoc_server.getThreatLevel() self.has_updated_prediction = True self.commands.pop(0) print 'Client: Command %s done' % cmd[0] if self.done: break print 'Client: Sleeping...' self.thread_event.wait() self.thread_event.clear() finally: self.commands = [] self.done = True def loadModel(self): self.commands.append(['loadModel']) self.thread_event.set() def setCamImage(self, img): self.commands.append(['setCamImage', img.copy()]) self.thread_event.set() def setCamImageByLocalFilename(self, img_fn): self.commands.append(['setCamImageByLocalFilename', img_fn]) self.thread_event.set() def setCamImageByFileContents(self, file_contents): self.commands.append(['setCamImageByFileContents', file_contents]) self.thread_event.set() def process(self): self.commands.append(['process']) self.thread_event.set() def hasUpdatedPrediction(self): if self.is_dummy: return True return self.has_updated_prediction def isQueueEmpty(self): return len(self.commands) == 0 def getPrediction(self): self.has_updated_prediction = False return self.last_prediction def getThreatLevel(self): self.has_updated_prediction = False return self.last_threat_level def quit(self): self.done = True self.thread_event.set() def __del__(self): self.done = True self.thread_event.set() if not self.conn is None: print 'Client: Disconnect' del self.conn self.conn = None
def connect(self): if self.deployment is None: self._mach = SshMachine(**self.kwargs) self.deployment = DeployedServer(self._mach) return self.deployment.classic_connect()
def __init__(self, host): self.host = host self.machine = SshMachine(self.host) self.rpyc_serv = DeployedServer(self.machine) self.rpyc_conn = self.rpyc_serv.classic_connect() self.rpyc_conn.ping()
class mdsConnector(object): """The mdsConnector class enables the use of MDSplus objects over an SSH connection to a remote host. All MDSplus objects are available and the data associated with MDSplus objects remain on the remote host until they are converted into native python objects or numpy data types. An application written based on the mdsConnector class can be used using the local MDSplus objects simply by not specifying a host when constructing the mdsConnector so those applications can work on local or remote data. One particularly interesting feature of the mdsConnector class is that unless you do not specify a host, the mdsConnector class works without the need to have any MDSplus packages or software installed on the local computer. The following is an example on its use: >>> from mdsconnector import mdsConnector >>> c=mdsConnector('remote-hostname') >>> t=c.Tree('treename',shotnum) >>> n=t.getNode('node-spec') >>> d1=n.record ##### data remains on remote host >>> d2=n.execute('$ + 10',d1) ##### data remains on remote host >>> d3=d2.data() ##### d3 is a numpy array on local host >>> d4=c.Data.execute('$ + 10',d3) ### d3 is sent to remote data remains on remote >>> d5=d4.data() ##### d5 is a numpy array on local host """ def __init__(self, host=None, user=None, port=None, keyfile=None, password=None, python_executable='python', ssh_opts=[], hop=None, hop_user=None, hop_port=None, hop_keyfile=None, hop_password=None, hop_python_executable='python'): """mdsConnector constructor. Specify host to connect to a remote host via ssh or omit host or specify None to use local MDSplus objects. Specify the full path of the python executable on the remote host if python is not in the default path""" if host is None: self.local = True import MDSplus self.mdsplus = MDSplus self.connection = None else: if python_executable == 'python': import sys if sys.version_info[0] == 3: python_executable = 'python3' self.local = False self.mach = SshMachine(host, user=user, port=port, keyfile=keyfile, password=password, ssh_opts=ssh_opts) self.server = DeployedServer(self.mach, python_executable=python_executable) self.connection = self.server.classic_connect() if hop is None: self.mdsplus = self.connection.modules['MDSplus'] try: self.dill = self.connection.modules['dill'] except: self.dill = None else: self.hop_connection = self.connection.modules[ 'mdsconnector'].mdsConnector( hop, user=hop_user, port=hop_port, keyfile=hop_keyfile, password=hop_password, python_executable=hop_python_executable) self.mdsplus = self.hop_connection.mdsplus def __getattr__(self, name): if self.connection: return mdsNetref(self, self.mdsplus.__dict__[name]) else: return self.mdsplus.__dict__[name]
import sys import rpyc from plumbum import SshMachine from rpyc.utils.zerodeploy import DeployedServer from rpyc.utils.splitbrain import splitbrain mach = SshMachine("192.168.1.117") print sys.platform with DeployedServer(mach) as dep: conn = dep.classic_connect() print conn.modules.sys.platform try: import posix except ImportError as ex: print ex with splitbrain(conn): import posix print posix.stat("/boot") print posix