From 37e9caa70fc372d4684688d396b8897efbab31af Mon Sep 17 00:00:00 2001 From: Adriana Date: Sat, 10 Apr 2010 11:24:29 +0300 Subject: [PATCH] created autorun directory for commander-server files. --- autorun/PROTOCOL | 64 +++++++++ autorun/README | 13 ++ autorun/Util.py | 32 +++++ autorun/commander/Client.py | 152 ++++++++++++++++++++ autorun/commander/ParserConf.py | 0 autorun/commander/SSHCommander.py | 50 +++++++ autorun/commander/TrafficControl.py | 108 +++++++++++++++ autorun/commander/XMLParser.py | 110 +++++++++++++++ autorun/commander/run.sh | 2 + autorun/server/AriaRun.py | 34 +++++ autorun/server/BitTorrentClientRun.py | 101 ++++++++++++++ autorun/server/Client.py | 113 +++++++++++++++ autorun/server/HrktorrentRun.py | 34 +++++ autorun/server/MainlineRun.py | 34 +++++ autorun/server/Server.py | 192 ++++++++++++++++++++++++++ autorun/server/Server_NO_DAEMON.py | 145 +++++++++++++++++++ autorun/server/TransmissionRun.py | 34 +++++ autorun/server/TriblerRun.py | 71 ++++++++++ autorun/server/VuzeRun.py | 34 +++++ autorun/server/daemon.py | 129 +++++++++++++++++ autorun/xml/clients.xml | 39 ++++++ autorun/xml/nodes.xml | 26 ++++ autorun/xml/swarm.xml | 23 +++ 23 files changed, 1540 insertions(+) create mode 100644 autorun/PROTOCOL create mode 100644 autorun/README create mode 100644 autorun/Util.py create mode 100644 autorun/commander/Client.py create mode 100644 autorun/commander/ParserConf.py create mode 100644 autorun/commander/SSHCommander.py create mode 100644 autorun/commander/TrafficControl.py create mode 100644 autorun/commander/XMLParser.py create mode 100755 autorun/commander/run.sh create mode 100644 autorun/server/AriaRun.py create mode 100644 autorun/server/BitTorrentClientRun.py create mode 100644 autorun/server/Client.py create mode 100644 autorun/server/HrktorrentRun.py create mode 100644 autorun/server/MainlineRun.py create mode 100644 autorun/server/Server.py create mode 100644 autorun/server/Server_NO_DAEMON.py create mode 100644 autorun/server/TransmissionRun.py create mode 100644 autorun/server/TriblerRun.py create mode 100644 autorun/server/VuzeRun.py create mode 100644 autorun/server/daemon.py create mode 100644 autorun/xml/clients.xml create mode 100644 autorun/xml/nodes.xml create mode 100644 autorun/xml/swarm.xml diff --git a/autorun/PROTOCOL b/autorun/PROTOCOL new file mode 100644 index 0000000..83f51fa --- /dev/null +++ b/autorun/PROTOCOL @@ -0,0 +1,64 @@ + +Comunicare Client <-> Server + + + +++---------+ start server +----------------------------------------------------------+ +| |---------------> | +--------------+ +--------+ +-------------+ | +| Client | send commands | | Server daemon| | tribler| | transmission| .... | +| |---------------> | +--------------+ +--------+ +-------------+ | +++---------+<--------------- +----------------------------------------------------------+ + ack + + + +1. Pas initial - NU MAI ESTE NEVOIE + - informatiile legate de clienti + - msg 1: tipul mesajului: CONFIG_MSG (definit in Util.py) + - msg 2: dictionar de dictionare cu datele din clients.xml + exp: {"tribler":{FILE:"Tribler/Tools/cmdline.py", + RUN_TYPE:"script", + INTERPRETER:"python", PREFIX:"PYTHONPATH=.",SUFFIX:"", + UP_LIMIT_OPTION:"",DL_LIMIT_OPTION:"", PORT_OPTION:"-p", + LOG_DIR_OPTION:"-l",DL_DIR_OPTION:"-d"} + } + - dupa fiecare msg 1,2 Serverul trimite un mesaj care indica daca a aparut sau nu vreo eroare + + + +2. Mesaje START + - trimis pt pornirea unui client + - msg 1: tipul mesajului START_MSG (definit in Util.py) + - msg 2: dictionar cu parametrii + exp: {CLIENT:"tribler", + BASE_DIR: "/usr/bin", + UP_LIMIT: "512", + DL_LIMIT:"256", + PORT:"9999", + DL_DIR:"/this/dir", + LOG_DIR:"/this/dir", + OUT_FILE: "output_file", ??? nu stim exact scopul lui + LOG_FILE:"log_file", + TORRENT: "torrent file" + } + + + - dupa fiecare msg 1,2 Serverul trimite un mesaj care indica daca a aparut sau nu vreo eroare + -> dupa msg 2 serverul trimite "" + +3. Mesaje STOP + - trimis pt oprirea unui client + - msg 1: STOP_MSG (definit in Util.py) + - msg 2: numele clientului (un string) + - dupa fiecare msg 1,2 Serverul trimite un mesaj care indica daca a aparut sau nu vreo eroare + +4. Mesaje STATUS + - trimise de client pt interogarea starii + - msg 1: tipul mesajului STATUS_MSG (definit in Util.py) + - msg 2: dictionar - TODO + - dupa fiecare msg 1,2 Serverul trimite un mesaj care indica daca a aparut sau nu vreo eroare + + + + +..... diff --git a/autorun/README b/autorun/README new file mode 100644 index 0000000..27db487 --- /dev/null +++ b/autorun/README @@ -0,0 +1,13 @@ +server/Server.py - serverul ce ruleaza ca daemon +server/Server_NO_DAEMON.py - folosit pt testarea functionarii, nu este daemon +server/Client.py - testeaza comunicatia cu serverul folosind sockets + - usage: python Client.py torrent_file +Util.py - constante folosite atat de server cat si de commander +start-clients/BitTorrentClientRun - porneste instante de clienti bittorrent +start-clients/*Run.py - subclase ale BitTorrentClientRun modificate pt fiecare client in parte. +commander/ -clasele pt Commander + + + + + diff --git a/autorun/Util.py b/autorun/Util.py new file mode 100644 index 0000000..d5da785 --- /dev/null +++ b/autorun/Util.py @@ -0,0 +1,32 @@ + +#!/usr/bin/env python + +SERVER_PORT = 10004 +SERVER_HOST = "127.0.0.1" + +""" Message types: client -> server """ + +START_MSG = "1"; +STOP_MSG = "2"; +STATUS_MSG = "3"; + +ACK_MSG = "ACK" # send by server to the client after receiving a message if everything was ok +ERROR_MSG = "ERROR " # send by server to the client if the parameters were incorrect + # or the client could not be started etc + +#xml tags from swarm.xml +CLIENT = "client" +BASE_DIR = "base" +UP_LIMIT = "upload_limit" +DL_LIMIT = "download_limit" +DL_DIR = "download_dir" +LOG_DIR = "logging_dir" +OUT_FILE = "output_file" +LOG_FILE = "log_file" +PORT = "port" +TORRENT = "torrent_file" + +#clients +TRIBLER = "tribler" +TRANSMISSION = "transmission" + diff --git a/autorun/commander/Client.py b/autorun/commander/Client.py new file mode 100644 index 0000000..e2b6d64 --- /dev/null +++ b/autorun/commander/Client.py @@ -0,0 +1,152 @@ +import sys, socket +import pickle +import paramiko +import os +from Util import * +from XMLParser import * +from TrafficControl import * +from threading import Thread +paramiko.util.log_to_file('/tmp/paramiko.log') + +MSGLEN = 1024 +DEBUG = True + +class Commander(Thread): + def __init__(self, nodes_xml, swarm_xml): + Thread.__init__(self) + self.nodes = Nodes(nodes_xml); + self.swarm = Swarm(swarm_xml); + self.tc = TrafficControl("openvz"); + self.sshc = paramiko.SSHClient() + self.sshc.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.sshc.load_system_host_keys() + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + def sendSSHComm(self, hostname, username, port, comm): + try: + self.sshc.connect(hostname=hostname, username=username, port=port) + stdin, stdout, stderr = self.sshc.exec_command(comm) + print stdout.readlines() + except Exception as e: + print e + finally: + self.sshc.close() + + def sendMultipleSSHComm(self, hostname, username, port, comms): + try: + self.sshc.connect(hostname=hostname, username=username, port=port) + for c in comms: + stdin, stdout, stderr = self.sshc.exec_command(comm) + except Exception as e: + print e + finally: + self.sshc.close() + + def sendComm(self, hostname, port, msg_type, config_data): + try: + self.sock.connect((hostname, port)) + self.send(msg_type) + response = self.recv_msg() + if response == ACK_MSG: + self.sendMsg(pickle.dumps(config_data)) + response = self.recv_msg() + print "->>>>>>>>>>>>>>>>>>>>>>>>>", response + except Exception as e: + print e + finally: + self.sock.close() + + def sendMsg(self, msg): + totalsent = 0 + while totalsent < len(msg): + sent = self.sock.send(msg[totalsent:]) + if sent == 0: + raise RuntimeError, "socket connection broken" + totalsent = totalsent + sent + + def recvMsg(self): + msg = '' + chunk = self.sock.recv(MSGLEN) + if chunk == '': + raise RuntimeError, "socket connection broken" + msg = msg + chunk + + return msg + + def startDaemon(self, node): + print node.daemon_dir + comm = "PYTHONPATH=/home/p2p/cs-p2p-next/bt_comm:/home/p2p/cs-p2p-next/bt_comm/start-clients/ python /home/p2p/cs-p2p-next/bt_comm/server/Server.py start " + node.public_address + " " + node.listen_port + print comm + #self.printDummyCommand(node.public_address, node.public_port, node.ssh_port, comm) + self.sendSSHComm(node.public_address, node.username, int(node.ssh_port), comm) + self.sendSSHComm(node.public_address, node.username, int(node.ssh_port), "ps -ef | grep Server") + + def applyTC(self, node): + si = self.swarm.getSIByNode(node) + self.tc.config(node.public_address, node.public_port, node.public_iface, \ + node.private_address, node.private_port, node.private_iface) + self.tc.set_upload_limit(si.upload_limit) + self.tc.set_download_limit(si.download_limit) + + commands = self.tc.get_all_commands() + self.printDummyCommand(node.public_address, node.public_port, node.ssh_port, commands) + #sendMultipleSSHComm(node.public_address, node.username, node.ssh_port, commands) + + def sendSIStart(self, si): + node = self.nodes.getNodeBySi(si) + base_path = node.getClientBaseDir(si.btclient) + torrent_file = self.swarm.getTorrentFile() + + config_data = {CLIENT : si.btclient, + BASE_DIR : base_path, + UP_LIMIT : si.download_limit, + DL_LIMIT : si.upload_limit, + PORT : node.public_port, + DL_DIR : si.download_dir, + LOG_DIR : si.log_dir, + OUT_FILE : si.output_file, + LOG_FILE : si.log_file, + TORRENT : torrent_file + } + + self.printDummyCommand(node.public_address, node.listen_port, START_MSG, config_data) + self.sendComm(node.public_address, int(node.listen_port), START_MSG, config_data) + + def printDummyCommand(self, public_address, public_port, option1, data): + print "----------------------" + print "sending to: [%s:%s] with option %s" %(public_address, public_port, option1) + print "this data: %s" %(data) + print "----------------------\n" + + + def sendSIStop(self, node): + pass + + def sendSIStatus(self, node): + pass + + def startAll(self): + for node in self.nodes.getNodes(): + #self.applyTC(node) + self.startDaemon(node) + + for si in self.swarm.getSIs(): + self.sendSIStart(si) + + def run(self): + self.printUsage() + while True: + k = raw_input("Choose option:") + if k == '': break + elif k == '1': + self.startAll() + + def printUsage(self): + print "=========Commander Options==========" + print "1. Start Swarm" + print "====================================" + +if __name__ == "__main__": + c = Commander("../xml/nodes.xml", "../xml/swarm.xml") + c.start() + diff --git a/autorun/commander/ParserConf.py b/autorun/commander/ParserConf.py new file mode 100644 index 0000000..e69de29 diff --git a/autorun/commander/SSHCommander.py b/autorun/commander/SSHCommander.py new file mode 100644 index 0000000..25bfcac --- /dev/null +++ b/autorun/commander/SSHCommander.py @@ -0,0 +1,50 @@ +import paramiko +import os +paramiko.util.log_to_file('/tmp/paramiko.log') + +class SSHCommander: + def __init__(self, hostname, username, port): + #self.sshclient = paramiko.Transport((hostname, port)) + self.sshclient = paramiko.SSHClient() + self.sshclient.set_missing_host_key_policy(paramiko.AutoAddPolicy()) + self.sshclient.load_system_host_keys() + #~ transport = paramiko.Transport((host, port)) + #pkey_file = os.path.expanduser('~/.ssh/id_rsa') + #self.pkey = paramiko.RSAKey.from_private_key_file(pkey_file) + self.hostname = hostname + self.username = username + self.port = port + + def connect(self): + self.sshclient.connect(hostname=self.hostname, username=self.username, port=self.port) + #self.sshclient.connect(username=self.username, pkey=self.pkey) + + def emitCommand(self, comm): + stdin, stdout, stderr = self.sshclient.exec_command(comm) + print stdout.readlines() + + def closeConnection(self): + self.sshclient.close() + + +sshc = SSHCommander("141.85.224.204", "p2p", 20322) +sshc.connect() +sshc.emitCommand("ls -lh") +sshc.closeConnection() + +#~ #client.connect(hostname='p2p-next-07.grid.pub.ro', username='p2p') +#~ stdin, stdout, stderr = client.exec_command('touch gugu dudu') +#~ stdin, stdout, stderr = client.exec_command('ls -l') +#~ print stdout.readlines() +#~ client.close() + + +#~ host = "p2p-next-09.grid.pub.ro" +#~ port = 22 +#~ transport = paramiko.Transport((host, port)) + +#~ privatekeyfile = os.path.expanduser('~/.ssh/id_rsa') +#~ mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile) +#~ username = 'p2p' +#~ transport.connect(username = username, pkey = mykey) + diff --git a/autorun/commander/TrafficControl.py b/autorun/commander/TrafficControl.py new file mode 100644 index 0000000..1abe51f --- /dev/null +++ b/autorun/commander/TrafficControl.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +""" + Traffic control interface for Linux tc + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import sqlite3 +import os.path + +DEBUG = False + +class TrafficControl: + """ + Basic class interface to Linux tc + """ + + def __init__(self, node_type): + self.node_type = node_type + self.upload_limit = -1 + self.download_limit = -1 + + def config(self, host_address, host_port, host_iface, + vm_address = None, vm_port = -1, vm_iface = None): + self.host_address = host_address + self.host_port = host_port + self.host_iface = host_iface + self.vm_address = vm_address + self.vm_port = vm_port + self.vm_iface = vm_iface + + """ + Set upload limit. Argument in KB/s (kilobytes/s) + """ + def set_upload_limit(self, upload_limit): + self.upload_limit = upload_limit + + """ + Set download limit. Argument in KB/s (kilobytes/s) + """ + def set_download_limit(self, download_limit): + self.download_limit = download_limit + + def get_upload_limit_commands(self): + upload_limit_commands = [] + upload_limit_commands.append("tc qdisc add dev %s root handle 1: htb default 90" % (self.vm_iface)) + upload_limit_commands.append("tc class add dev %s parent 1: classid 1:1 htb rate %skb ceil %skb" % (self.vm_iface, self.upload_limit, self.upload_limit)) + upload_limit_commands.append("tc qdisc add dev %s parent 1:1 handle 10: sfq perturb 10" % (self.vm_iface)) + upload_limit_commands.append("tc filter add dev %s parent 1:0 protocol ip u32 match ip dst %s match ip dport %s 0xffff classid 1:1" % (self.vm_iface, self.vm_address, self.vm_port)) + + return upload_limit_commands + + def get_download_limit_commands(self): + download_limit_commands = [] + download_limit_commands.append("tc qdisc add dev %s root handle 1: htb default 90" % (self.host_iface)) + download_limit_commands.append("tc class add dev %s parent 1: classid 1:1 htb rate %skb ceil %skb" % (self.host_iface, self.download_limit, self.download_limit)) + download_limit_commands.append("tc qdisc add dev %s parent 1:1 handle 10: sfq perturb 10" % (self.host_iface)) + download_limit_commands.append("tc filter add dev %s parent 1:0 protocol ip u32 match ip src %s classid 1:1" % (self.host_iface, self.vm_address)) + + return download_limit_commands + + def get_flush_commands(self): + flush_commands = [] + flush_commands.append("tc qdisc del dev %s root handle 1:" % (self.host_iface)) + flush_commands.append("tc qdisc del dev %s root handle 1:" % (self.vm_iface)) + + return flush_commands + + def get_all_commands(self): + all_commands = [] + all_commands.extend(self.get_upload_limit_commands()) + all_commands.extend(self.get_download_limit_commands()) + all_commands.extend(self.get_flush_commands()) + + return all_commands + + +def print_commands(commands, header): + print "\n\t== %s ==\n" % (header) + + for c in commands: + print c + +def main(): + + """ + Test case + """ + + tc = TrafficControl("openvz") + tc.config("141.85.224.201", 10150, "eth0", + "172.16.10.0", 10150, "venet0") + tc.set_upload_limit(512) + tc.set_download_limit(256) + + upload_limit_commands = tc.get_upload_limit_commands() + download_limit_commands = tc.get_download_limit_commands() + flush_commands = tc.get_flush_commands() + all_commands = tc.get_all_commands() + + print_commands(upload_limit_commands, "upload limit commands") + print_commands(download_limit_commands, "download limit commands") + print_commands(flush_commands, "flush commands") + print_commands(all_commands, "all commands") + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/commander/XMLParser.py b/autorun/commander/XMLParser.py new file mode 100644 index 0000000..25be3af --- /dev/null +++ b/autorun/commander/XMLParser.py @@ -0,0 +1,110 @@ +from lxml import etree + +class SwarmInstance: + def __init__(self, id, list): + self.id = id; + self.node_id = list[0]; + self.btclient = list[1]; + self.upload_limit = list[2]; + self.download_limit = list[3]; + self.download_dir = list[4]; + self.log_dir = list[5]; + self.log_file = list[6]; + self.output_dir = list[7]; + self.output_file = list[8]; + + def __str__(self): + return '[%s: %s: %s: %s: %s: %s: %s: %s]' \ + %(self.id, self.node_id, self.btclient, self.upload_limit, \ + self.download_limit, self.download_dir, self.log_dir, self.output_dir); + +class Node: + def __init__(self, id, list): + self.id = id; + self.public_address = list[0]; + self.public_port = list[1]; + self.public_iface = list[2]; + self.private_address = list[3]; + self.private_port = list[4]; + self.private_iface = list[5]; + self.ssh_port = list[6]; + self.username = list[7]; + self.listen_port = list[8]; + self.clients_base_dir = list[10]; + self.daemon_dir = list[9]; + + def __str__(self): + return '[%s: %s: %s: %s: %s: %s %s: %s]' \ + %(self.id, self.public_address, self.public_port, self.private_address, \ + self.private_port, self.ssh_port, self.username, self.clients_base_dir); + + def getClientBaseDir(self, client): + return self.clients_base_dir[client] + +class Nodes: + def __init__(self, nodes_xml): + try: + tree = etree.parse(nodes_xml) + root = tree.getroot() + self.nodes = [] + for elem in root: + id = elem.get("id") + list = [elem2.text for elem2 in elem[:len(elem)-1]] + client_paths = {} + for elem2 in elem[len(elem)-1]: + client_id = elem2.get("id"); + client_paths [client_id]=elem2[0].text; + list.append(client_paths); + self.nodes.append(Node(id, list)) + except IOError as e: + print e + return None + + def getNode(self, id): + for node in self.nodes: + if node.id == id: + return node + + def getNodeBySi(self, si): + for node in self.nodes: + if node.id == si.node_id: + return node + + def getNodes(self): + return self.nodes + + +class Swarm: + def __init__(self, swarm_xml): + try: + tree = etree.parse(swarm_xml) + root = tree.getroot() + self.swarm = [] + self.torrent_file = root[0].text + for elem in root[1:]: + id = elem.get("id") + list = [elem2.text for elem2 in elem[:len(elem)-1]] + self.swarm.append(SwarmInstance(id, list)) + except IOError as e: + print e + return None + + def getSIByNode(self, node): + for si in self.swarm: + if si.node_id == node.id: + return si + + def getTorrentFile(self): + return self.torrent_file + + def getSIs(self): + return self.swarm + +#~ swarm = Swarm("swarm.xml") +#~ for si in swarm.getSIs(): + #~ print si + +#~ nodes = Nodes("nodes.xml") +#~ for node in nodes.getNodes(): + #~ print node + #~ print node.getClientBaseDir('libtorrent') diff --git a/autorun/commander/run.sh b/autorun/commander/run.sh new file mode 100755 index 0000000..9a41b17 --- /dev/null +++ b/autorun/commander/run.sh @@ -0,0 +1,2 @@ +#!/bin/bash +PYTHONPATH=/home/marius/cs-p2p-next/bt_comm/:/home/marius/cs-p2p-next/bt_comm/xml/ python Client.py diff --git a/autorun/server/AriaRun.py b/autorun/server/AriaRun.py new file mode 100644 index 0000000..f955872 --- /dev/null +++ b/autorun/server/AriaRun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" + Base class for running Aria client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class AriaRun(BitTorrentClientRun): + def __init__(self, base_path): + BitTorrentClientRun.__init__(self, base_path, + "$base_path/src/aria2c --log-level=debug --dir=$download_dir --log=$log_dir/$log_file --torrent-file=$torrent_file &> $output_dir/$output_file", + "$base_path/src/aria2c --log-level=debug --dir=$download_dir --log=$log_dir/$log_file --torrent-file=$torrent_file &> $output_dir/$output_file") + + +def main(): + + """ + Test case + """ + + ar = AriaRun("/home/p2p/p2p-clients/aria") + ar.config_run("/home/p2p/p2p-dld/aria", "/home/p2p/p2p-log/aria", "aria-fedora.out", "/home/p2p/p2p-log/aria", "aria-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + ar.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/BitTorrentClientRun.py b/autorun/server/BitTorrentClientRun.py new file mode 100644 index 0000000..935c19d --- /dev/null +++ b/autorun/server/BitTorrentClientRun.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python + +""" + Base class for running BitTorrent client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os +import os.path +import subprocess +import shlex +from string import Template + +DEBUG = True + +class BitTorrentClientRun: + def __init__(self, base_path, simple_run_expr, logging_run_expr): + self.base_path = base_path + self.simple_run_expr = simple_run_expr + self.logging_run_expr = logging_run_expr + + def config_run(self, download_dir, output_dir, output_file, log_dir, log_file, port, torrent_file): + self.download_dir = download_dir + self.output_dir = output_dir + self.output_file = output_file # output from stdout + self.log_dir = log_dir + self.log_file = log_file # output from stderr + self.port = port + self.torrent_file = torrent_file + + def start(self): + t = Template(self.simple_run_expr) + self.simple_run_command = t.substitute( + base_path = self.base_path, + download_dir = self.download_dir, + output_dir = self.output_dir, + output_file = self.output_file, + log_dir = self.log_dir, + log_file = self.log_file, + port = str(self.port), + torrent_file = self.torrent_file + ) + + t = Template(self.logging_run_expr) + self.logging_run_command = t.substitute( + base_path = self.base_path, + download_dir = self.download_dir, + output_dir = self.output_dir, + output_file = self.output_file, + log_dir = self.log_dir, + log_file = self.log_file, + port = str(self.port), + torrent_file = self.torrent_file + ) + + print self.simple_run_command + print self.logging_run_command + + def run_client(self, command): + + # split command + args = shlex.split(command) + + # remove redirectation parameters + for i in range(0, len(args)): + if args[i].find(">") > -1 : + for j in range(i, len(args)): + args.pop(i) + break; + if(DEBUG): + print "BitTorrentClientRun: command =", args + + log_redirect = open(self.log_dir+"/"+self.log_file,"w") + output_redirect = open(self.output_dir+"/"+self.output_file,"w") + p=subprocess.Popen(args, shell=False, #does not create sh process + stdout=log_redirect, + stderr=output_redirect) + pid = p.pid + if(DEBUG): + print "BitTorrentClientRun: pid =", pid + return [pid, log_redirect, output_redirect] + + +def main(): + + """ + Test case + + btcr = BitTorrentClientRun("/home/p2p/p2p-clients/transmission", + "$base_path/cli/transmissioncli --download-dir $download_dir --port $port $torrent_file > $output_dir/$output_file", + "TR_DEBUG=2 $base_path/cli/transmissioncli --download-dir $download_dir --port $port $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file") + btcr.config_run("/home/p2p/p2p-dld/transmission", "/home/p2p/p2p-log/transmission", "transmission-fedora.out", "/home/p2p/p2p-log/transmission", "transmission-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + btcr.start() + + + """ + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/Client.py b/autorun/server/Client.py new file mode 100644 index 0000000..ae461cf --- /dev/null +++ b/autorun/server/Client.py @@ -0,0 +1,113 @@ +import sys,time, socket +import pickle +from Util import * +MSGLEN = 1024 +DEBUG = True +class MySocket: + def __init__(self, sock=None): + if sock is None: + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + else: + self.sock = sock + + def connect(self, host, port): + self.sock.connect((host, port)) + print "connected to %s %s"%(host, port) + + def send_msg(self, msg): + totalsent = 0 + while totalsent < len(msg): + sent = self.sock.send(msg[totalsent:]) + if sent == 0: + raise RuntimeError, "socket connection broken" + totalsent = totalsent + sent + + def send_command(self, msg_type, config_data): + self.send_msg(msg_type) + print "am trimis ", msg_type + response = self.recv_msg() + if response == ACK_MSG: + self.send_dict(config_data) + print "am trimis" + response = self.recv_msg() + + return response + + def recv_msg(self): + msg = '' + chunk = self.sock.recv(MSGLEN) + if chunk == '': + raise RuntimeError, "socket connection broken" + msg = msg + chunk + print "am primit ", msg + return msg + + # send a pickled dictionary + def send_dict(self, data): + dumped_data = pickle.dumps(data) + self.send_msg(dumped_data) + +# basic test that starts and stops a BT Client +def test_all_commands(torrent_file): + s = MySocket() + s.connect(SERVER_HOST, SERVER_PORT) + torrent_name = torrent_file[(torrent_file.rfind("/")+1):torrent_file.find(".torrent")]; + + start_data_tribler = { + CLIENT: TRIBLER, PORT:10150, + BASE_DIR:"/home/p2p/p2p-clients/tribler", + TORRENT:"/home/p2p/p2p-meta/" + torrent_name+".torrent", + DL_DIR: "/home/p2p/p2p-dld/tribler", + LOG_DIR: "/home/p2p/p2p-log/tribler", + OUT_FILE: torrent_name + ".out", #status messages + LOG_FILE: "tribler-" + torrent_name + ".log", #verbose messages + + } + start_data_transmission = { + CLIENT: TRANSMISSION, PORT:10250, + BASE_DIR:"/usr/bin/", + TORRENT: "/home/p2p/p2p-meta/" + torrent_name+".torrent", + DL_DIR: "/home/p2p/p2p-dld/transmission", + LOG_DIR: "/home/p2p/p2p-log/transmission", + OUT_FILE: torrent_name + ".out", #status messages + LOG_FILE: "transmission-" + torrent_name + ".log", #verbose messages + + } + + start_data_hrktorrent = { + CLIENT: HRKTORRENT, PORT:10350, + BASE_DIR:"/home/p2p/p2p-clients/hrktorrent", + TORRENT: "/home/p2p/p2p-meta/" + torrent_name+".torrent", + DL_DIR: "/home/p2p/p2p-dld/hrktorrent", + LOG_DIR: "/home/p2p/p2p-log/hrktorrent", + OUT_FILE: torrent_name + ".out", #status messages + LOG_FILE: "hrktorrent-" + torrent_name + ".log", #verbose messages + + + } + response = s.send_command(START_MSG, start_data_tribler) + print response + pid = (response.split(" "))[1] + print pid + s = MySocket() + s.connect(SERVER_HOST, SERVER_PORT) + time.sleep(100) + response = s.send_command(STOP_MSG, pid) + print response + +def test_send_recv(): + # test 1 + + s.send_msg("hello") + # test 2 + dd = {'a':1, 'b':2} + s.send_dict(dd) + s.recv_msg() + + +if __name__ == "__main__": + + if len(sys.argv) != 2: + print "Usage: python %s "%sys.argv[0] + else: + test_all_commands(sys.argv[1]) diff --git a/autorun/server/HrktorrentRun.py b/autorun/server/HrktorrentRun.py new file mode 100644 index 0000000..812cf3b --- /dev/null +++ b/autorun/server/HrktorrentRun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" + Base class for running libtorrent (hrktorrent) client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class HrktorrentRun(BitTorrentClientRun): + def __init__(self, base_path): + BitTorrentClientRun.__init__(self, base_path, + "cd $download_dir && $base_path/hrktorrent --minport$port --maxport$port $torrent_file &> $output_dir/$output_file", + "cd $download_dir && $base_path/hrktorrent --minport$port --maxport$port $torrent_file &> $output_dir/$output_file") + + +def main(): + + """ + Test case + """ + + hr = HrktorrentRun("/home/p2p/p2p-clients/hrktorrent") + hr.config_run("/home/p2p/p2p-dld/hrktorrent", "/home/p2p/p2p-log/hrktorrent", "hrktorrent-fedora.out", "/home/p2p/p2p-log/hrktorrent", "hrktorrent-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + hr.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/MainlineRun.py b/autorun/server/MainlineRun.py new file mode 100644 index 0000000..ec65599 --- /dev/null +++ b/autorun/server/MainlineRun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" + Base class for running BitTorrent (Mainline) client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class MainlineRun(BitTorrentClientRun): + def __init__(self, base_path): + BitTorrentClientRun.__init__(self, base_path, + "$base_path/bittorrent-console.py --save_in $download_dir --display_interval 1 $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file", + "$base_path/bittorrent-console.py --save_in $download_dir --display_interval 1 $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file") + + +def main(): + + """ + Test case + """ + + mr = MainlineRun("/home/p2p/p2p-clients/mainline") + mr.config_run("/home/p2p/p2p-dld/mainline", "/home/p2p/p2p-log/mainline", "mainline-fedora.out", "/home/p2p/p2p-log/mainline", "mainline-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + mr.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/Server.py b/autorun/server/Server.py new file mode 100644 index 0000000..9976613 --- /dev/null +++ b/autorun/server/Server.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python + +import sys, os, socket +import pickle +import signal +from daemon import Daemon +from Util import * +from Util import SERVER_HOST, SERVER_PORT +from BitTorrentClientRun import * +from TransmissionRun import * +from TriblerRun import * + +DEBUG = True + + +class MyDaemon(Daemon): + + ip = "" + port = 0 + BUFFER_SIZE = 4096 + + states = {} # keeps track of what kind of message was previously receveid on a socket. + processes = {} + WAITING_MSG_TYPE = 0 + WAITING_START_DATA = 3 + WAITING_STOP_DATA = 4 + WAITING_STATUS_DATA = 5 + + def __init__(self, pidfile, ip='', port = 0, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): + Daemon.__init__(self, pidfile, stdin, stdout, stderr) + self.ip = ip + self.port = port + + def set_address(self, ip): + self.ip = ip + print "am setat ip ", ip + + def set_port(self, port): + self.port = port + print "am setat port ", port + + def run(self): + self.doServer(self.ip, self.port) + + def recv_pickled_data(self, clientsock): + # while chunk: + # chunk = clientsock.recv(self.BUFFER_SIZE) + # data += chunk + data = clientsock.recv(self.BUFFER_SIZE) + dd = pickle.loads(data) + return dd + + + """ Starts a process for a BitTorrent client and returns its pid. + @return: -1, if any error is encountered + """ + def start_bt_client(self, bt_client_data): + + btcr = None + + if bt_client_data[CLIENT] == TRANSMISSION: + btcr = TransmissionRun(bt_client_data[BASE_DIR]) + elif bt_client_data[CLIENT] == TRIBLER: + btcr = TriblerRun(bt_client_data[BASE_DIR]) + + else: + return -1 + + btcr.config_run(bt_client_data[DL_DIR], bt_client_data[LOG_DIR], + bt_client_data[OUT_FILE], bt_client_data[LOG_DIR], + bt_client_data[LOG_FILE], bt_client_data[PORT], + bt_client_data[TORRENT]) + + btcr.start() + [pid, log_fd, output_fd] = btcr.run_client(btcr.simple_run_command) + self.processes[pid] = (log_fd, output_fd) + print self.processes[pid] + if(DEBUG): + print "Server: started client with pid = ", pid + return pid + + """Simple test + + btcr = TransmissionRun("/usr/bin/transmissioncli") + btcr.config_run("/home/adriana/p2p/p2p-dld/transmission", + "/home/adriana/p2p/p2p-log/transmission", + "scrubs.out", "/home/adriana/p2p/", + "transmission-scrubs.log", 10150, + "/home/adriana/p2p/p2p-meta/scrubs.torrent") + + btcr.start() + btcr.run_client(btcr.simple_run_command) + """ + + def stop_bt_client(self, pid): + + int_pid = int(pid) + os.kill(int_pid, signal.SIGKILL) # kill generates zombies + os.wait() + self.processes[int_pid][0].close() + self.processes[int_pid][1].close() + del self.processes[int_pid] + if(DEBUG): + print "Server: killed process with pid = ", pid + + def doServer(self, ip, port): + + serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + if(DEBUG): + print "Server: host ip = %s, port = %d"%(SERVER_HOST,SERVER_PORT) + serversocket.bind((ip,port)); + serversocket.listen(10) #max 10 requests + clientsocks = [] + while(1): + if(DEBUG): + print "Server: accepting connections" + (clientsock, address) = serversocket.accept(); + if(DEBUG): + print "Server: accepted connection from ", address + + if clientsock not in self.states: + self.states[clientsock] = self.WAITING_MSG_TYPE; + + if self.states[clientsock] == self.WAITING_MSG_TYPE: + print self.states[clientsock] + msg = clientsock.recv(self.BUFFER_SIZE) + if(DEBUG): + print "Server: received message:\n", msg + msg_types = { + START_MSG: self.WAITING_START_DATA, + STOP_MSG: self.WAITING_STOP_DATA, + STATUS_MSG: self.WAITING_STATUS_DATA + } + if msg not in msg_types: + clientsock.send(ERROR_MSG +"wrong message type " + msg) + else: + self.states[clientsock] = msg_types[msg] + clientsock.send(ACK_MSG) + #else: + print self.states[clientsock] + + if self.states[clientsock] == self.WAITING_START_DATA: + bt_client_data = self.recv_pickled_data(clientsock) + if(DEBUG): + print "Server: received message:\n", msg + client_pid = self.start_bt_client(bt_client_data) + clientsock.send(ACK_MSG +" "+ str(client_pid)) + + elif self.states[clientsock] == self.WAITING_STOP_DATA: + client_pid = self.recv_pickled_data(clientsock) + if(DEBUG): + print "Server: received message:\n", msg + self.stop_bt_client(client_pid) + clientsock.send(ACK_MSG) + + elif self.states[clientsock] == self.WAITING_STATUS_DATA: + config = self.recv_pickled_data(clientsock) + clientsock.send(ACK_MSG) + + self.states[clientsock] = self.WAITING_MSG_TYPE + + # clientsock.recv(self.BUFFER_SIZE) + # recv_pickled_data(clientsock) + clientsock.close() + +if __name__ == "__main__": + + if len(sys.argv) >= 2: + + if 'start' == sys.argv[1]: + if(len(sys.argv) != 4): + print "usage:\n\t %s start " % sys.argv[0] + sys.exit(2) + daemon = MyDaemon('/tmp/daemon-example.pid', sys.argv[2], int(sys.argv[3]), stdout = '/home/p2p/out', stderr = 'home/p2p/err') + daemon.start() + elif 'stop' == sys.argv[1]: + daemon = MyDaemon('/tmp/daemon-example.pid') + daemon.stop() + elif 'restart' == sys.argv[1]: + daemon = MyDaemon('/tmp/daemon-example.pid') + daemon.restart() + else: + print "Unknown command" + sys.exit(2) + sys.exit(0) + else: + print "usage:\n\t %s start " % sys.argv[0] + print "\t%s stop|restart " % sys.argv[0] + sys.exit(2) + + diff --git a/autorun/server/Server_NO_DAEMON.py b/autorun/server/Server_NO_DAEMON.py new file mode 100644 index 0000000..2745331 --- /dev/null +++ b/autorun/server/Server_NO_DAEMON.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python + +import sys, os, socket +import pickle +import signal +from daemon import Daemon +from Util import * +from Util import SERVER_HOST, SERVER_PORT +from BitTorrentClientRun import * +from TransmissionRun import * +from TriblerRun import * +BUFFER_SIZE = 4096 + +states = {} # keeps track of what kind of message was previously receveid on a socket. +processes = {} +WAITING_MSG_TYPE = 0 +WAITING_START_DATA = 3 +WAITING_STOP_DATA = 4 +WAITING_STATUS_DATA = 5 + +DEBUG = True + +def recv_pickled_data(clientsock): + # while chunk: + # chunk = clientsock.recv(BUFFER_SIZE) + # data += chunk + data = clientsock.recv(BUFFER_SIZE) + dd = pickle.loads(data) + return dd + + +def start_bt_client(bt_client_data): + + btcr = None + + if bt_client_data[CLIENT] == TRANSMISSION: + #btcr = TransmissionRun("/usr/bin/transmissioncli") + btcr = TransmissionRun(bt_client_data[BASE_DIR]) + elif bt_client_data[CLIENT] == TRIBLER: + btcr = TriblerRun(bt_client_data[BASE_DIR]) + # btcr = TriblerRun("/home/p2p/p2p-clients/tribler") + + else: + return -1 + + btcr.config_run(bt_client_data[DL_DIR], bt_client_data[LOG_DIR], + bt_client_data[OUT_FILE], bt_client_data[LOG_DIR], + bt_client_data[LOG_FILE], bt_client_data[PORT], + bt_client_data[TORRENT]) + + btcr.start() + [pid, log_fd, output_fd] = btcr.run_client(btcr.simple_run_command) + processes[pid] = (log_fd, output_fd) + print processes[pid] + if(DEBUG): + print "Server: started client with pid = ", pid + return pid + + """Simple test + + btcr = TransmissionRun("/usr/bin/transmissioncli") + btcr.config_run("/home/adriana/p2p/p2p-dld/transmission", + "/home/adriana/p2p/p2p-log/transmission", + "scrubs.out", "/home/adriana/p2p/", + "transmission-scrubs.log", 10150, + "/home/adriana/p2p/p2p-meta/scrubs.torrent") + + btcr.start() + btcr.run_client(btcr.simple_run_command) + """ + +def stop_bt_client(pid): + + int_pid = int(pid) + os.kill(int_pid, signal.SIGKILL) # kill generates zombies + os.wait() + processes[int_pid][0].close() + processes[int_pid][1].close() + del processes[int_pid] + if(DEBUG): + print "Server: killed process with pid = ", pid + +def doServer(): + + serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if(DEBUG): + print "Server: host ip = %s, port = %d"%(SERVER_HOST,SERVER_PORT) + serversocket.bind((SERVER_HOST, SERVER_PORT)); + serversocket.listen(10) #max 10 requests + clientsocks = [] + while(1): + if(DEBUG): + print "Server: accepting connections" + (clientsock, address) = serversocket.accept(); + if(DEBUG): + print "Server: accepted connection from ", address + + if clientsock not in states: + states[clientsock] = WAITING_MSG_TYPE; + + if states[clientsock] == WAITING_MSG_TYPE: + print states[clientsock] + msg = clientsock.recv(BUFFER_SIZE) + if(DEBUG): + print "Server: received message:\n", msg + msg_types = { + START_MSG: WAITING_START_DATA, + STOP_MSG: WAITING_STOP_DATA, + STATUS_MSG: WAITING_STATUS_DATA + } + if msg not in msg_types: + clientsock.send(ERROR_MSG +"wrong message type " + msg) + else: + states[clientsock] = msg_types[msg] + clientsock.send(ACK_MSG) + #else: + print states[clientsock] + + if states[clientsock] == WAITING_START_DATA: + bt_client_data = recv_pickled_data(clientsock) + if(DEBUG): + print "Server: received message:\n", msg + client_pid = start_bt_client(bt_client_data) + clientsock.send(ACK_MSG +" "+ str(client_pid)) + + elif states[clientsock] == WAITING_STOP_DATA: + client_pid = recv_pickled_data(clientsock) + if(DEBUG): + print "Server: received message:\n", msg + stop_bt_client(client_pid) + clientsock.send(ACK_MSG) + + elif states[clientsock] == WAITING_STATUS_DATA: + config = recv_pickled_data(clientsock) + clientsock.send(ACK_MSG) + + states[clientsock] = WAITING_MSG_TYPE + + # clientsock.recv(BUFFER_SIZE) + # recv_pickled_data(clientsock) + clientsock.close() + +if __name__ == "__main__": + doServer() + diff --git a/autorun/server/TransmissionRun.py b/autorun/server/TransmissionRun.py new file mode 100644 index 0000000..a1953a5 --- /dev/null +++ b/autorun/server/TransmissionRun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" + Base class for running Transmission client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class TransmissionRun(BitTorrentClientRun): + def __init__(self, base_path): + BitTorrentClientRun.__init__(self, base_path, + "$base_path/transmission --download-dir $download_dir --port $port $torrent_file > $output_dir/$output_file", + "TR_DEBUG=2 $base_path/transmission --download-dir $download_dir --port $port $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file") + + +def main(): + + """ + Test case + """ + + tr = TransmissionRun("/home/p2p/p2p-clients/transmission") + tr.config_run("/home/p2p/p2p-dld/transmission", "/home/p2p/p2p-log/transmission", "transmission-fedora.out", "/home/p2p/p2p-log/transmission", "transmission-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + tr.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/TriblerRun.py b/autorun/server/TriblerRun.py new file mode 100644 index 0000000..8e62760 --- /dev/null +++ b/autorun/server/TriblerRun.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +""" + Base class for running Tribler client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class TriblerRun(BitTorrentClientRun): + def __init__(self, base_path): + + self.set_PYTHONPATH(base_path) + BitTorrentClientRun.__init__(self, base_path, + "python $base_path/Tribler/Tools/cmdlinedl.py -o $download_dir -p $port $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file", + "python $base_path/Tribler/Tools/cmdlinedl.py -o $download_dir -p $port $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file") + + + """ + Adds lines in cmdlinedl.py that set the PYTHONPATH variable. + """ + def set_PYTHONPATH(self, base_path): + filename = base_path + "/Tribler/Tools/cmdlinedl.py" + tmp_filename = filename + "_tmp" + if not os.path.exists(filename) or not os.path.isfile(filename): + print "Error: invalid Tribler path ", filename + return + f = open(filename, "r"); + f_copy = open(tmp_filename, "w"); + import_line = "import sys" + instr_line = "\nsys.path.append('"+base_path+"')\n" + exists = False + position = -1 + exists = False + for line in f: + if line.find("import")>=0 and line.find("sys")>=0 and (not line.find("sys."))>=0: + #position = f.tell() + len(line) + 1 + f_copy.write(line) + f_copy.write(instr_line) + continue + if line == instr_line: + exists = True + break + f_copy.write(line) + + f_copy.close() + f.close() + if not exists: + os.remove(filename) + os.rename(tmp_filename, filename) + else: + os.remove(tmp_filename) + +def main(): + + """ + Test case + """ + + tr = TriblerRun("/home/p2p/p2p-clients/tribler") + #tr.config_run("/home/p2p/p2p-dld/tribler", "/home/p2p/p2p-log/tribler", "tribler-fedora.out", "/home/p2p/p2p-log/tribler", "tribler-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + #tr.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/VuzeRun.py b/autorun/server/VuzeRun.py new file mode 100644 index 0000000..c6ba26e --- /dev/null +++ b/autorun/server/VuzeRun.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python + +""" + Base class for running Transmission client instances + 2010, Razvan Deaconescu, razvan.deaconescu@cs.pub.ro +""" + +import sys +import os.path +from BitTorrentClientRun import BitTorrentClientRun + +DEBUG = False + + +class TransmissionRun(BitTorrentClientRun): + def __init__(self, base_path): + BitTorrentClientRun.__init__(self, base_path, + "$base_path/cli/transmissioncli --download-dir $download_dir --port $port $torrent_file > $output_dir/$output_file", + "TR_DEBUG=2 $base_path/cli/transmissioncli --download-dir $download_dir --port $port $torrent_file 2> $log_dir/$log_file > $output_dir/$output_file") + + +def main(): + + """ + Test case + """ + + tr = TransmissionRun("/home/p2p/p2p-clients/transmission") + tr.config_run("/home/p2p/p2p-dld/transmission", "/home/p2p/p2p-log/transmission", "transmission-fedora.out", "/home/p2p/p2p-log/transmission", "transmission-fedora.log", 10150, "/home/p2p/p2p-meta/fedora.torrent") + tr.start() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/autorun/server/daemon.py b/autorun/server/daemon.py new file mode 100644 index 0000000..f371720 --- /dev/null +++ b/autorun/server/daemon.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +import sys, os, time, atexit +from signal import SIGTERM + +class Daemon: + """ + A generic daemon class. + + Usage: subclass the Daemon class and override the run() method + """ + def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): + self.stdin = stdin + self.stdout = stdout + self.stderr = stderr + self.pidfile = pidfile + + def daemonize(self): + """ + do the UNIX double-fork magic, see Stevens' "Advanced + Programming in the UNIX Environment" for details (ISBN 0201563177) + http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 + """ + try: + pid = os.fork() + if pid > 0: + # exit first parent + sys.exit(0) + except OSError, e: + sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror)) + sys.exit(1) + + # decouple from parent environment + os.chdir("/") + os.setsid() + os.umask(0) + + # do second fork + try: + pid = os.fork() + if pid > 0: + # exit from second parent + sys.exit(0) + except OSError, e: + sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror)) + sys.exit(1) + + # redirect standard file descriptors + sys.stdout.flush() + sys.stderr.flush() + si = file(self.stdin, 'r') + so = file(self.stdout, 'a+') + se = file(self.stderr, 'a+', 0) + os.dup2(si.fileno(), sys.stdin.fileno()) + os.dup2(so.fileno(), sys.stdout.fileno()) + os.dup2(se.fileno(), sys.stderr.fileno()) + + # write pidfile + atexit.register(self.delpid) + pid = str(os.getpid()) + file(self.pidfile,'w+').write("%s\n" % pid) + + def delpid(self): + os.remove(self.pidfile) + + def start(self): + """ + Start the daemon + """ + # Check for a pidfile to see if the daemon already runs + try: + pf = file(self.pidfile,'r') + pid = int(pf.read().strip()) + pf.close() + except IOError: + pid = None + + if pid: + message = "pidfile %s already exist. Daemon already running?\n" + sys.stderr.write(message % self.pidfile) + sys.exit(1) + + # Start the daemon + self.daemonize() + self.run() + + def stop(self): + """ + Stop the daemon + """ + # Get the pid from the pidfile + try: + pf = file(self.pidfile,'r') + pid = int(pf.read().strip()) + pf.close() + except IOError: + pid = None + + if not pid: + message = "pidfile %s does not exist. Daemon not running?\n" + sys.stderr.write(message % self.pidfile) + return # not an error in a restart + + # Try killing the daemon process + try: + while 1: + os.kill(pid, SIGTERM) + time.sleep(0.1) + except OSError, err: + err = str(err) + if err.find("No such process") > 0: + if os.path.exists(self.pidfile): + os.remove(self.pidfile) + else: + print str(err) + sys.exit(1) + + def restart(self): + """ + Restart the daemon + """ + self.stop() + self.start() + + def run(self): + """ + You should override this method when you subclass Daemon. It will be called after the process has been + daemonized by start() or restart(). + """ diff --git a/autorun/xml/clients.xml b/autorun/xml/clients.xml new file mode 100644 index 0000000..f8a805c --- /dev/null +++ b/autorun/xml/clients.xml @@ -0,0 +1,39 @@ + + + + + Tribler/Tools/cmdlinedl.py + python + PYTHONPATH=. + + + + + -p + -l + -d + + + + hrktorrent + + + + + -p + -d + + + + src/transmission-cli + + + + + -u + -d + -p + -l + -o + + diff --git a/autorun/xml/nodes.xml b/autorun/xml/nodes.xml new file mode 100644 index 0000000..514bb2b --- /dev/null +++ b/autorun/xml/nodes.xml @@ -0,0 +1,26 @@ + + + + 141.85.224.204 + 10150 + eth0 + 172.16.20.3 + + venet0:0 + 20322 + p2p + 10004 + /home/p2p/cs-p2p-next/bt_comm/server + + + /home/p2p/p2p-clients/tribler/ + + + /home/p2p/p2p-clients/libtorrent/ + + + /home/p2p/p2p-clients/transmission/ + + + + diff --git a/autorun/xml/swarm.xml b/autorun/xml/swarm.xml new file mode 100644 index 0000000..4899737 --- /dev/null +++ b/autorun/xml/swarm.xml @@ -0,0 +1,23 @@ + + + /home/p2p/p2p-meta/bbt316.torrent + + 1 + tribler + 512 + 256 + /home/p2p/p2p-dld/tribler + /home/p2p/p2p-log/tribler + tribler-bbt316.log + /home/p2p/p2p-log/tribler + tribler-bbt316.out + + + + + + + + + + -- 2.20.1