Skip to content

Commit

Permalink
check if port is occupied before starting kolibri and show more info …
Browse files Browse the repository at this point in the history
…for kolibri stop
  • Loading branch information
lyw07 committed Mar 7, 2018
1 parent 8e7de99 commit ef9050b
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 8 deletions.
28 changes: 20 additions & 8 deletions kolibri/utils/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

from . import server # noqa
from .system import become_daemon # noqa
from .sanity_checks import check_other_kolibri_running # noqa

USAGE = """
Kolibri
Expand Down Expand Up @@ -262,12 +263,9 @@ def start(port=None, daemon=True):
# https://github.com/learningequality/kolibri/issues/1615
update()

if port is None:
try:
port = int(os.environ['KOLIBRI_LISTEN_PORT'])
except ValueError:
logger.error("Invalid KOLIBRI_LISTEN_PORT, must be an integer")
raise
# In case that some tests run start() function only
if not isinstance(port, int):
port = _get_port(port)

if not daemon:
logger.info("Running 'kolibri start' in foreground...")
Expand Down Expand Up @@ -314,6 +312,7 @@ def stop():
pid, __, __ = server.get_status()
server.stop(pid=pid)
stopped = True
logger.info("Kolibri server has been successfully stoppped.")
except server.NotRunning as e:
verbose_status = "{msg:s} ({code:d})".format(
code=e.status_code,
Expand Down Expand Up @@ -576,6 +575,17 @@ def parse_args(args=None):
return docopt(USAGE, **docopt_kwargs), django_args


def _get_port(port):
port = int(port) if port else None
if port is None:
try:
port = int(os.environ['KOLIBRI_LISTEN_PORT'])
except ValueError:
logger.error("Invalid KOLIBRI_LISTEN_PORT, must be an integer")
raise
return port


def main(args=None):
"""
Kolibri's main function. Parses arguments and calls utility functions.
Expand All @@ -589,6 +599,10 @@ def main(args=None):

debug = arguments['--debug']

if arguments['start']:
port = _get_port(arguments['--port'])
check_other_kolibri_running(port)

initialize(debug=debug)

# Alias
Expand All @@ -607,8 +621,6 @@ def main(args=None):
return

if arguments['start']:
port = arguments['--port']
port = int(port) if port else None
daemon = not arguments['--foreground']
if sys.platform == 'darwin':
daemon = False
Expand Down
42 changes: 42 additions & 0 deletions kolibri/utils/sanity_checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import logging
import socket
import sys

from .server import get_status
from .server import NotRunning

logger = logging.getLogger(__name__)

def check_other_kolibri_running(port):
try:
# Check if there are other kolibri instances running
# If there are, then we need to stop users from starting kolibri again.
pid, listen_address, listen_port = get_status()
logger.error(
"There is another Kolibri server running. "
"Please use `kolibri stop` and try again.")
sys.exit(1)

except NotRunning:
# In case that something other than Kolibri occupies the port,
# check the port's availability.
check_port_availability('127.0.0.1', port)


def check_port_availability(host, port):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# This is to prevent the previous execution has left the socket
# in a TIME_WAIT start, and can't be immediately reused.
# From the bottom of https://docs.python.org/2/library/socket.html#example
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
s.bind((host, port))
s.close()
except socket.error:
# Port is occupied
logger.error(
"Port {} is occupied.\n"
"Please check that you do not have other processes "
"running on this port and try again.\n".format(port))
s.close()
sys.exit(1)

0 comments on commit ef9050b

Please sign in to comment.