I've got the right environment setup, python 2.7.5, Twisted installed and imports work in the Python Shell.
I have a very simple Server instance to display a landing page that Works on local machine fine.
from twisted.web import http
class MyRequestHandler(http.Request):
pages={
'/': '<h1>Geo-Address Server</h1>Twisted Server is Up and Running..',
'/test': '<h1>Test</h1>Test page',
}
def process(self):
print self.path
if self.pages.has_key(self.path):
self.write(self.pages[self.path])
else:
self.setResponseCode(http.NOT_FOUND)
self.write("<h1>Not Found</h1>Sorry, page does not exist")
self.finish()
class MyHttp(http.HTTPChannel):
requestFactory=MyRequestHandler
class MyHttpFactory(http.HTTPFactory):
protocol=MyHttp
if __name__=='__main__':
from twisted.internet import reactor
reactor.listenTCP(8080, MyHttpFactory())
reactor.run()
However, deploying this on the Openshift Server fails to run. If I try to run the script
python script.py &
I get:
reactor.listenTCP(8080, MyHttpFactory()) File "/var/lib/openshift/5378ea844382ec89da000432/python/virtenv/lib/python2.7/site-packages/twisted/internet/posixbase.py", line 495, in listenTCP p.startListening() File "/var/lib/openshift/5378ea844382ec89da000432/python/virtenv/lib/python2.7/site-packages/twisted/internet/tcp.py", line 979, in startListening raise CannotListenError(self.interface, self.port, le) twisted.internet.error.CannotListenError: Couldn't listen on any:8080: [Errno 13] Permission denied.
Reading through SO, most people just say to bind to port 8080(which I have done), but still I get the same error.
As the kb says
Please note: We don't allow arbitrary binding of ports on the externally accessible IP address.
It is possible to bind to the internal IP with port range: 15000 - 35530. All other ports are reserved for specific processes to avoid conflicts. Since we're binding to the internal IP, you will need to use port forwarding to access it: https://openshift.redhat.com/community/blogs/getting-started-with-port-forwarding-on-openshift
Therefor, just find out the $OPENSHIFT_PYTHON_IP
echo $OPENSHIFT_PYTHON_IP
Then add that address to the reactor listener's interface
reactor.listenTCP(15000, MyHttpFactory(), interface='127.X.X.X')
Alternative(and the best) way to do it is by picking the value in the code. That way, if the IP changes dynamically, you still get the current IP
import os
local_hostname =os.getenv("OPENSHIFT_INTERNAL_IP")
..
..
reactor.listenTCP(15000, MyHttpFactory(), interface=local_hostname)
Note: You can only bind to the port range (15000-35530)