psychomario/PyPXE — pull request #50 by mmattioli (2014-07-15 20:21:39+00:00)
Title: Reorganize and Prepare for First Release

Overview
===
Before we make our first release official, we should clean up the structure of the PyPXE repository as well as enhance the portability of PyPXE services for use as a library.

Repo Restructuring
---
**Relocating**
I created a directory called `pypxe` and put all of the service files in that directory so that PyPXE functions more as a library. Importing the services can be one one of the following ways:
```python
from pypxe import tftp
```
```python
import pypxe.tftp
```
```python
from pypxe import tftp, dhcp, http
```
**Renaming**
I renamed `server.py` to `pypxe-server.py` for more intuitive use. This is the file that showcases what PyPXE can do and how to use it, it's name should be succinct yet specific and I think `pypxe-server.py` does that well.

I also renamed each service file to `tftp.py`, `dhcp.py`, and `http.py` as they implement services and not necessarilly _just_ the servers they're named after. For example, `DHCPD()` is a class _within_ `dhcp.py` and if we decide to implement other DHCP-related clases later on the naming of `dhcp.py` should allow for that.

Using Library Services
---
**Keyword Arguments w/Defaults**
Since many of the services implemented use a rather long list of arguments, I implemented keyword arguments with default values for each service. This implementation closes #43.

For example, the following is how `DHCPD()` is now constructed:
```python
def __init__(self, **serverSettings):

self.ip = serverSettings.get('ip', '192.168.2.2')
self.port = serverSettings.get('port', 67)
self.offerfrom = serverSettings.get('offerfrom', '192.168.2.100')
self.offerto = serverSettings.get('offerto', '192.168.2.150')
self.subnetmask = serverSettings.get('subnetmask', '255.255.255.0')
self.router = serverSettings.get('router', '192.168.2.1')
self.dnsserver = serverSettings.get('dnsserver', '8.8.8.8')
self.broadcast = serverSettings.get('broadcast', '')
self.fileserver = serverSettings.get('fileserver', '192.168.2.2')
self.filename = serverSettings.get('filename', 'pxelinux.0')
self.ipxe = serverSettings.get('useipxe', False)
self.http = serverSettings.get('usehttp', False)
self.mode_proxy = serverSettings.get('mode_proxy', False) #ProxyDHCP mode
self.mode_debug = serverSettings.get('mode_debug', False) #debug mode
self.magic = struct.pack('!I', 0x63825363) #magic cookie
```
Previously, it was constructed using the following:
```python
def __init__(
self,
ip = '192.168.2.2',
port = 67,
offerfrom = '192.168.2.100',
offerto = '192.168.2.150',
subnetmask = '255.255.255.0',
router = '192.168.2.1',
dnsserver = '8.8.8.8',
broadcast = '',
fileserver = '192.168.2.2',
filename = 'pxelinux.0',
useipxe = False,
usehttp = False,
mode_proxy = False,
mode_debug = False):

self.ip = ip
self.port = port
self.offerfrom = offerfrom
self.offerto = offerto
self.subnetmask = subnetmask
self.router = router
self.dnsserver = dnsserver
self.broadcast = broadcast
self.fileserver = fileserver
self.filename = filename
self.magic = struct.pack('!I', 0x63825363) #magic cookie
self.ipxe = useipxe
self.mode_proxy = mode_proxy #ProxyDHCP mode
self.mode_debug = mode_debug #debug mode
```
The improved implementation allows for better portability as well as control as users must now send arguments using keywords or a dictionary rather than listing them all.

**Improved Debugging**
Debugging is now universal, simply enabling `--debug` on `pypxe-server.py` enables debugging modes on all services that were enabled.

Debugging statements are also much cleaner and the only non-debugging output that the services give are warnings.

Documentation
---
All documentation has been updated to reflect all of the aforementioned changes and improvements. The documentation is very clean and easy to read/follow so that users understand how to use PyPXE either as a library or as a standalone service with `pypxe-server.py`.