aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuciano Resende <lresende@apache.org>2017-01-23 19:57:25 -0800
committerLuciano Resende <lresende@apache.org>2017-01-23 19:57:25 -0800
commit72324c513db7ec0f5338a1abe04d85642587e618 (patch)
treef8248529d241a96044918c0c7199723679158631
parentd592198c0115da2fff47abfc4734b9ba822d454e (diff)
downloadtoree-gateway-72324c513db7ec0f5338a1abe04d85642587e618.tar.gz
toree-gateway-72324c513db7ec0f5338a1abe04d85642587e618.tar.bz2
toree-gateway-72324c513db7ec0f5338a1abe04d85642587e618.zip
Python doc for classes and methods
-rw-r--r--python/config.py10
-rw-r--r--python/lifecycle.py34
-rw-r--r--python/toree_manager.py45
-rw-r--r--python/toree_profile.py37
4 files changed, 111 insertions, 15 deletions
diff --git a/python/config.py b/python/config.py
index e7e69ea..479f165 100644
--- a/python/config.py
+++ b/python/config.py
@@ -19,6 +19,16 @@ import os.path
import configparser
class ConfigManager:
+ """
+ Simple configuration manager
+
+ This expects TOREE_GATEWAY_HOME environment variable
+ to be set and will look for the config file in
+ TOREE_GATEWAY_HOME/conf/toree-gateway.properties
+
+ In dev environment, it will fallback to reading
+ the config file
+ """
config = configparser.RawConfigParser()
homePath = os.getcwd()[:-7]
configPath = None
diff --git a/python/lifecycle.py b/python/lifecycle.py
index 39e1638..bbc58d2 100644
--- a/python/lifecycle.py
+++ b/python/lifecycle.py
@@ -22,6 +22,15 @@ from config import *
from toree_manager import *
class LifecycleManager:
+ """
+ A Orchestrator for Toree Lifecycle which select an available
+ toree sloot, reserv it and start/stop when notebooks are
+ started/stopped.
+
+ Open slots are identified by a not having a toree.pid. In case
+ of corruption or a requirement to kill the toree process, one
+ should also remove the toree.id from the specific Toree slot.
+ """
configManager = None
toreeManager = None
@@ -31,8 +40,9 @@ class LifecycleManager:
def _reserve_profile(self):
"""
- Tries to reserv a profile configuration to access Toree
- :return: the reserved profile folder location, or None
+ Tries to reserve an available toree slot
+
+ :return: the reserved Toree slot or None
"""
profilesFolder = self.configManager.getProfilesFolder()
profile = None
@@ -53,12 +63,23 @@ class LifecycleManager:
return profile
def _release_profile(self, profile):
+ """
+ Release the provided Toree slot
+
+ :param profile: the Toree slot that was previously reserved
+ :return: None
+ """
profile.release()
def start_toree(self):
"""
- Reserve a profile to use, and start a remote Toree instance with that configuration
- :return: the path to the configuration file (profile.json) to use when connecting
+ Reserve a open Toree slot, and start a remote Toree
+ instance with the configuration provided
+
+ :return: the path to the Toree configuration file
+ (profile.json) which was used to start Toree. A
+ runtime error is thrown in case of no more available
+ Toree slots.
"""
profile = self._reserve_profile()
if profile is None:
@@ -68,6 +89,11 @@ class LifecycleManager:
return profile
def stop_toree(self, profile):
+ """
+ Stop remote Toree instance and release Toree slot
+ :param profile: the toree slot that was previously reserved
+ :return: None
+ """
self.toreeManager.stop_toree(profile)
self._release_profile(profile)
diff --git a/python/toree_manager.py b/python/toree_manager.py
index 996ad9e..2784067 100644
--- a/python/toree_manager.py
+++ b/python/toree_manager.py
@@ -31,12 +31,20 @@ from toree_profile import *
from config import *
class ToreeManager:
+ """
+ A Helper class that enables connecting to a remote machine
+ via SSH and properly start/stop Toree instances
+ """
configManager = None
def __init__(self):
self.configManager = ConfigManager()
- def getSSHClient(self):
+ def _getSSHClient(self):
+ """
+ Configure and initialize a SSH client
+ :return: a configured SSH client
+ """
client = SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
@@ -46,11 +54,14 @@ class ToreeManager:
username=self.configManager.get('toree.username'), \
password=self.configManager.get('toree.password'))
- #print('Client connected successfuly')
-
return client
- def getSSHChannel(self, client):
+ def _getSSHChannel(self, client):
+ """
+ Configure and initialize a new SSH session on the client
+ :param client: The client to initialize the session
+ :return: the new SSH session
+ """
channel = client.invoke_shell()
channel.settimeout(20)
channel.set_combine_stderr(True)
@@ -58,9 +69,16 @@ class ToreeManager:
return channel
def start_toree(self, profile):
+ """
+ Connect to a remote system via SSH and
+ start an instance of Toree
+ :param profile: The Toree slot to read profile.json
+ configuration file
+ :return: None
+ """
try:
- client = self.getSSHClient()
- channel = self.getSSHChannel(client)
+ client = self._getSSHClient()
+ channel = self._getSSHChannel(client)
channel = client.invoke_shell()
channel.settimeout(30)
@@ -84,9 +102,6 @@ class ToreeManager:
config['iopub_port'], \
config['hb_port'])
-
- #print(command)
-
stdin.write(command)
pid = None
@@ -114,9 +129,17 @@ class ToreeManager:
print('all closed')
def stop_toree(self, profile):
+ """
+ Connect to a remote system via SSH and
+ stop the associated Toree instance based on the
+ process id information stored in toree.pid
+ :param profile: The Toree slot to read toree.pid
+ configuration file
+ :return: None
+ """
try:
- client = self.getSSHClient()
- channel = self.getSSHChannel(client)
+ client = self._getSSHClient()
+ channel = self._getSSHChannel(client)
stdin = channel.makefile('w')
stdout = channel.makefile('r')
diff --git a/python/toree_profile.py b/python/toree_profile.py
index eaadc9d..b306b76 100644
--- a/python/toree_profile.py
+++ b/python/toree_profile.py
@@ -21,6 +21,10 @@ import json
import time
class Profile:
+ """
+ Abstract the handling of a toree slot providing access
+ to configuration, process id, and any manipulations
+ """
PROCESS_FILE_NAME = "toree.pid"
CONFIGURATION_FILE_NAME = "profile.json"
@@ -30,28 +34,57 @@ class Profile:
self.profilePath = profilePath
def pidLocation(self):
+ """
+ The location for the pid file
+ :return: absolute path to pid file
+ """
return self.profilePath + '/' + self.PROCESS_FILE_NAME
def configurationLocation(self):
+ """
+ The location for the profile.json configuration file
+ :return: absolute path to the profile.json
+ """
return self.profilePath + '/' + self.CONFIGURATION_FILE_NAME
def isAvailable(self):
+ """
+ Weather or not the Toree slot is available
+ :return: true in case the slot is available (no pid file)
+ """
taken = os.path.exists(self.pidLocation())
return not taken
def reserve(self):
+ """
+ Reserve the slot profile by adding a pid file into it
+ :return:
+ """
open(self.pidLocation(), 'a').close()
def release(self):
+ """
+ Release the slot profile by removing the pid file from it
+ :return:
+ """
if os.path.exists(self.pidLocation()):
os.remove(self.pidLocation())
def pid(self):
+ """
+ The Toree process id
+ :return: the pid number or None
+ """
with open(self.pidLocation(), 'r') as pid_file:
data = pid_file.read()
return data
def updatePid(self, pid):
+ """
+ Update the contents of the pid file
+ :param pid: The pid value
+ :return:
+ """
try:
file = open(self.pidLocation(), 'w')
file.write(pid)
@@ -59,6 +92,10 @@ class Profile:
file.close
def config(self):
+ """
+ The parsed content of the profile.json
+ :return:
+ """
with open(self.configurationLocation(), 'r') as data_file:
return json.load(data_file) #, object_hook=util._byteify