aboutsummaryrefslogtreecommitdiff
path: root/src/fe/net
diff options
context:
space:
mode:
authorAndrew Gaffney <agaffney@gentoo.org>2005-05-02 15:11:30 +0000
committerAndrew Gaffney <agaffney@gentoo.org>2005-05-02 15:11:30 +0000
commit988c887ab0711e78a135b4ff77e928ec06e0789e (patch)
tree8e7f66595087a26c9b37a74734994eeed7f6b226 /src/fe/net
parentremove duff import (diff)
downloadgli-988c887ab0711e78a135b4ff77e928ec06e0789e.tar.gz
gli-988c887ab0711e78a135b4ff77e928ec06e0789e.tar.bz2
gli-988c887ab0711e78a135b4ff77e928ec06e0789e.zip
added netfe
git-svn-id: svn+ssh://svn.gentoo.org/var/svnroot/gli/trunk@546 f8877401-5920-0410-a79b-8e2d7e04ca0d
Diffstat (limited to 'src/fe/net')
-rw-r--r--src/fe/net/client/netfe.py147
-rw-r--r--src/fe/net/server/netbe.py119
2 files changed, 266 insertions, 0 deletions
diff --git a/src/fe/net/client/netfe.py b/src/fe/net/client/netfe.py
new file mode 100644
index 0000000..ca46fe8
--- /dev/null
+++ b/src/fe/net/client/netfe.py
@@ -0,0 +1,147 @@
+#!/usr/bin/python
+"""
+The sole point of this script is to kick off a GLIInstall. This script requires the 'netbe.py' configured and setup on the local net in order to run. No other dependancies are required for this script.
+Script steps:
+ 1. Bring up network with dhcp or use udp broadcast to grab the client config file.
+ 2. Send a UDP request to the broadcast address.
+ 3. The server will check the ip making the request and sent it the location of the server
+ 4. The client will connect to the server using XMLRPC and request a GLIClientConfig and a InstallProfile
+ 5. Next the client will start the install, logging all events to the server
+"""
+import sys, time, socket
+sys.path.append("../..")
+import GLIException
+import GLIInstallProfile
+import GLIClientConfiguration
+import GLIClientController
+import GLIUtility
+
+def udp_broadcast(message, bw_addr, port):
+ #Setup the socket for broadcast.
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.bind(('', 0))
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+ retry_max = 10
+ count = 0
+ response = ""
+
+ while 1:
+ s.sendto(message, (bw_addr, port))
+ response, fromaddr = s.recvfrom(1024)
+ count = count + 1
+ if response:
+ break
+ if count >= retry_max:
+ raise GLIException("NoBroadcastServer", 'fatal', 'udp_broadcast',"Was unable to find a network broadcast server.")
+ time.sleep(2)
+ return response, str(fromaddr[0]), str(fromaddr[1])
+
+def setup_network(main_port):
+ discovery_port = main_port - 1
+ device = None
+ device_name = ""
+ for num in range(5):
+ device = GLIUtility.get_eth_info(num)
+ if device:
+ device_name = 'eth' + str(num)
+ break
+ else:
+ raise GLIException("NoInterfaceError", 'fatal', 'setup_network',"Was unable to find a network inferface.")
+
+ #First try to come up as a dhcp client. This is the preferred way of starting the network.
+ if device:
+ status = GLIUtility.spawn("dhcpcd -n " + device_name, quiet=True)
+ else:
+ status = GLIUtility.spawn("dhcpcd -n", quiet=True)
+
+ #If dhcp couldn't start we will try to use UDP broadcast to the server. Then we will pull the
+ #config file and setup whatever networking is defined for us.
+ if not GLIUtility.exitsuccess(status):
+ GLIUtility.set_ip(device_name, '0.0.0.0', '255.255.255.255', '0.0.0.0')
+
+ #Grab the config from the server. Pass it the MAC address so the server can identify you.
+ #as well as the broadcast address and port you want to check on.
+ response, server_ip, port = udp_broadcast("GLI CC " + device[0], device[3], discovery_port)
+ if response == "GLI CC not found!":
+ raise GLIException("GLIMissingConfig","The server does not have a GLICLientConfiguration for you. Check with the server admin.")
+ else:
+ #Write the Client Config to a temp file, so it can be read in and parsed
+ file = open("/tmp/gli.conf","w")
+ file.write(response)
+ file.close()
+
+ #Instanciate a ClientController and tell it to setup the network
+ client_config = GLIClientConfiguration.GLIClientConfiguration()
+ client_config.parse("/tmp/gli.conf")
+ cc = GLIClientController.GLIClientController(client_config)
+ cc.configure_networking()
+ response, server_ip, server_port = udp_broadcast("PING", device[3], discovery_port)
+ return server_ip
+
+
+if __name__ == '__main__':
+ main_port = 12345
+
+ #First things first check for network existance and setup the network; the server ip will be returned
+ server_ip = setup_network(main_port)
+ local_ip = socket.gethostbyname(socket.gethostname())
+
+ #Next setup the RPC Client
+ server = ServerProxy("http://" + server_ip + ":" + main_port)
+
+ #Grab the Client Configuration and Install Profile
+ client_config = ""
+ install_profile = ""
+ try:
+ client_config = server.get_client_config(local_ip)
+ install_profile = server.get_install_profile(local_ip)
+ except Error, v:
+ raise GLIException("GLIMissingConfig", v )
+
+ #Write out the client_config and install_profile
+ file = open("/tmp/gli.conf","w")
+ file.write(client_config)
+ file.close()
+
+ file = open("/tmp/ins_prof.xml","w")
+ file.write(install_profile)
+ file.close()
+
+ #Instanciate the GLI engine
+ client_conf = GLIClientConfiguration.GLIClientConfiguration()
+ client_conf.parse("/tmp/gli.conf")
+ client_conf.set_interactive(None, True, None)
+ install_prof = GLIInstallProfile.GLIInstallProfile()
+ install_prof.parse("/tmp/ins_prof.xml")
+ cc = GLIClientController.GLIClientController(client_conf,install_prof)
+
+ #Start the backend threads
+ cc.start_pre_install()
+
+ #Begin the main engine
+ cc.start_install()
+ num_steps_completed = 1
+ while 1:
+ notification = cc.getNotification()
+ if notification == None:
+ time.sleep(1)
+ continue
+ type = notification.get_type()
+ data = notification.get_data()
+ if type == "exception":
+ server.log_event(local_ip, "Exception: " + data)
+ elif type == "int":
+ if data == GLIClientController.NEXT_STEP_READY:
+ next_step_waiting = False
+ next_step = cc.get_next_step_info()
+ num_steps = cc.get_num_steps()
+ server.log_event(local_ip, "On step " + num_steps_completed + " of " + num_steps + ". Current step: " + next_step)
+ num_steps_completed += 1
+ if cc.has_more_steps():
+ cc.next_step()
+ continue
+ if data == GLIClientController.INSTALL_DONE:
+ server.log_event(local_ip, "Install completed!")
+ print "Install done!"
+ sys.exit(0) \ No newline at end of file
diff --git a/src/fe/net/server/netbe.py b/src/fe/net/server/netbe.py
new file mode 100644
index 0000000..101c5ee
--- /dev/null
+++ b/src/fe/net/server/netbe.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+"""
+This script will setup two servers and then run forever.
+The first is a udp discovery server. Its job it to tell any clients where
+the other server is. Also it can send out a client config file to allow static
+ip address boxes to use the service as well.
+The second server is a XMLRPC server that will serve config files and allow network
+based logging. Naming conventions are as follows:
+
+config_dir
+ |
+ 192.168.0.3.cc.xml #Client Config File
+ 192.168.0.3.ip.xml #Install Profile File
+ 192.168.0.3.log #Log for that ip
+ main.log #Main log
+It is also recommended that if you don't use dhcp that you make a symbolic link of the
+computer's mac address to the ip version of the cc.xml file. Otherwise the box will not
+be able to start the install.
+Ex. 01:23:45:67:89:ab.cc.xml -> 192.168.0.3.cc.xml
+"""
+import sys,os,socket,shelve
+sys.path.append("../..")
+import SimpleXMLRPCServer
+import xmlrpclib
+import GLIUtility
+import GLIClientController
+
+#The XMLRPC class
+class GLINetBe:
+ def __init__(self, loc):
+ self._path = loc
+
+ def get_client_config(self, ip):
+ if not GLIUtility.is_file(self._path + ip + ".cc.xml"):
+ return xmlrpclib.Fault("GLIMissingConfig","The server does not have a GLICLientConfiguration for you. Check with the server admin.")
+ file = open(self._path + ip + ".cc.xml", "r")
+ data = file.read()
+ file.close()
+ return data
+
+ def get_install_profile(self, ip):
+ if not GLIUtility.is_file(self._path + ip + ".ip.xml"):
+ return xmlrpclib.Fault("GLIMissingConfig","The server does not have a InstallProfile for you. Check with the server admin.")
+ file = open(self._path + ip + ".ip.xml", "r")
+ data = file.read()
+ file.close()
+ return data
+
+ def log_event(self, ip, data):
+
+ file = open(self._path + ip + ".log", "a")
+ file.write(data)
+ file.close()
+ file = open(self._path + "main.log", "a")
+ file.write(data)
+ file.close()
+
+#start network discovery service
+def register(local_port, cc_path):
+ pid = os.fork()
+ if pid == 0:
+ host = ''
+ port = local_port - 1 #It will send out the information on a port one less than the RPCServer's port
+ buf = 1024
+ addr = (host,port)
+ # Create socket and bind to address
+ UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
+ UDPSock.bind(addr)
+ UDPSock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
+
+ # Receive messages
+ while 1:
+ data, fromaddr = UDPSock.recvfrom(buf)
+ if not data:
+ print "Client has exited!"
+ break #Serve forever
+ else:
+ print "\nReceived message '" + data + "' from " + fromaddr[0] + ":" + str(fromaddr[1])
+
+ if data == "GLIInstallAuto":
+ file = open(cc_path + fromaddr[0] + "cc.xml", "r")
+ data = file.read()
+ file.close()
+ elif data == "PING":
+ data = "PONG"
+ else:
+ data = "GLIClientConfiguration not found!"
+ UDPSock.sendto(data, (fromaddr[0], fromaddr[1]))
+
+ # Close socket
+ UDPSock.close()
+ sys.exit(0)
+ return pid
+
+#start XMLRPCServer
+def rpc_start(port, db_loc):
+ pid = os.fork()
+ if pid == 0:
+ #start XMLRPCServer
+ server = SimpleXMLRPCServer.SimpleXMLRPCServer(("localhost", port))
+ server.register_introspection_functions()
+ server.register_instance(GLINetBe(db_loc))
+ server.serve_forever()
+ sys.exit(0)
+ return pid
+
+if __name__ == '__main__':
+ local_port = 12345
+ loc = "/tmp/install/" #Where all the config files are
+ if not os.path.isdir(loc):
+ print "You must specify a valid directory!"
+ sys.exit(0)
+
+ pid1 = register(local_port, loc)
+ pid2 = rpc_start(local_port, loc)
+
+ #Wait for the child processes to exit
+ os.waitpid(pid1,0)
+ os.waitpid(pid2,0)