Skip to content

Commit

Permalink
Merge pull request #14 from lsst-sqre/tickets/DM-27353
Browse files Browse the repository at this point in the history
[DM-27353] Allow configuration of mobu nublado url
  • Loading branch information
cbanek authored Oct 30, 2020
2 parents 1100757 + 64f088f commit f278b10
Show file tree
Hide file tree
Showing 16 changed files with 106 additions and 49 deletions.
8 changes: 8 additions & 0 deletions dev-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
gafaelfawr_secrets_path: "secret/k8s_operator/minikube.lsst.codes/gafaelfawr"
mobu_secrets_path: "secret/k8s_operator/minikube.lsst.codes/mobu"
environment_url: "https://minikube.lsst.codes"
host: "minikube.lsst.codes"

image:
tag: dev
pullPolicy: Never
4 changes: 4 additions & 0 deletions iterate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash -ex
helm delete --purge mobu-dev || true
docker build -t lsstsqre/mobu:dev .
helm upgrade --install mobu-dev lsstsqre/mobu --namespace mobu-dev --values dev-values.yaml
12 changes: 9 additions & 3 deletions scripts/cbanek.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"username": "cbanek",
"uidnumber": 55411,
"business": "JupyterLoginLoop"
"name": "cbanek",
"user": {
"username": "cbanek",
"uidnumber": 55411
},
"business": "JupyterLoginLoop",
"options": {
"restart": true
}
}
11 changes: 8 additions & 3 deletions scripts/lsptestuser01.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"username": "lsptestuser01",
"uidnumber": 60181,
"name": "lsptestuser01",
"user": {
"username": "lsptestuser01",
"uidnumber": 60181
},
"business": "JupyterLoginLoop",
"restart": true
"options": {
"restart": true
}
}
11 changes: 8 additions & 3 deletions scripts/lsptestuser02.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"username": "lsptestuser02",
"uidnumber": 60182,
"name": "lsptestuser02",
"user": {
"username": "lsptestuser02",
"uidnumber": 60182
},
"business": "JupyterLoginLoop",
"restart": true
"options": {
"restart": true
}
}
11 changes: 8 additions & 3 deletions scripts/lsptestuser03.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"username": "lsptestuser03",
"uidnumber": 60183,
"name": "lsptestuser03",
"user": {
"username": "lsptestuser03",
"uidnumber": 60183
},
"business": "JupyterLoginLoop",
"restart": true
"options": {
"restart": true
}
}
11 changes: 8 additions & 3 deletions scripts/lsptestuser04.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"username": "lsptestuser04",
"uidnumber": 60184,
"name": "lsptestuser04",
"user": {
"username": "lsptestuser04",
"uidnumber": 60184
},
"business": "JupyterLoginLoop",
"restart": true
"options": {
"restart": true
}
}
11 changes: 8 additions & 3 deletions scripts/lsptestuser05.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
{
"username": "lsptestuser05",
"uidnumber": 60185,
"name": "Robo-Simon",
"user": {
"username": "lsptestuser05",
"uidnumber": 60185
},
"business": "NotebookRunner",
"restart": true
"options": {
"restart": true
}
}
3 changes: 2 additions & 1 deletion src/mobu/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import asyncio
from dataclasses import dataclass
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any, Dict

if TYPE_CHECKING:
from mobu.monkey import Monkey
Expand All @@ -15,6 +15,7 @@
@dataclass
class Business:
monkey: "Monkey"
options: Dict[str, Any]

async def run(self) -> None:
logger = self.monkey.log
Expand Down
17 changes: 8 additions & 9 deletions src/mobu/jupyterclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import string
from dataclasses import dataclass
from http.cookies import BaseCookie
from typing import Any, Dict
from uuid import uuid4

from aiohttp import ClientSession
Expand All @@ -33,14 +34,18 @@ class JupyterClient:
log: BoundLoggerLazyProxy
user: User
session: ClientSession
headers: dict
headers: Dict[str, str]
xsrftoken: str
jupyter_url: str

def __init__(self, user: User, log: BoundLoggerLazyProxy):
def __init__(
self, user: User, log: BoundLoggerLazyProxy, options: Dict[str, Any]
):
self.user = user
self.log = log
self.jupyter_url = Configuration.environment_url + "/nb/"
self.jupyter_url = Configuration.environment_url + options.get(
"nb_url", "/nb/"
)
self.xsrftoken = "".join(
random.choices(string.ascii_uppercase + string.digits, k=16)
)
Expand All @@ -66,12 +71,6 @@ async def hub_login(self) -> None:
if r.status != 200:
raise Exception(f"Error {r.status} from {r.url}")

home_url = self.jupyter_url + "hub/home"
if str(r.url) != home_url:
raise Exception(
f"Redirected to {r.url} but expected {home_url}"
)

async def ensure_lab(self) -> None:
self.log.info("Ensure lab")
running = await self.is_lab_running()
Expand Down
4 changes: 3 additions & 1 deletion src/mobu/jupyterloginloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ async def run(self) -> None:
try:
logger = self.monkey.log
logger.info("Starting up...")
self._client = JupyterClient(self.monkey.user, logger)
self._client = JupyterClient(
self.monkey.user, logger, self.options
)

await self._client.hub_login()
logger.info("Logged into hub")
Expand Down
2 changes: 1 addition & 1 deletion src/mobu/jupyterpythonloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ async def run(self) -> None:
logger = self.monkey.log
logger.info("Starting up...")

client = JupyterClient(self.monkey.user, logger)
client = JupyterClient(self.monkey.user, logger, self.options)
await client.hub_login()
await client.ensure_lab()

Expand Down
15 changes: 11 additions & 4 deletions src/mobu/monkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from dataclasses import dataclass
from datetime import datetime
from tempfile import NamedTemporaryFile
from typing import IO
from typing import IO, Any, Dict

import structlog
from aiohttp import ClientSession
Expand All @@ -27,6 +27,7 @@

@dataclass
class Monkey:
name: str
user: User
log: BoundLoggerLazyProxy
business: Business
Expand All @@ -36,9 +37,11 @@ class Monkey:
_job: Job
_logfile: IO[bytes]

def __init__(self, user: User):
def __init__(self, name: str, user: User, options: Dict[str, Any]):
self.name = name
self.state = "IDLE"
self.user = user
self.restart = options.get("restart", False)

self._logfile = NamedTemporaryFile()

Expand All @@ -52,7 +55,7 @@ def __init__(self, user: User):
streamHandler = logging.StreamHandler(stream=sys.stdout)
streamHandler.setFormatter(formatter)

logger = logging.getLogger(self.user.username)
logger = logging.getLogger(self.name)
logger.handlers.clear()
logger.setLevel(logging.INFO)
logger.addHandler(fileHandler)
Expand All @@ -63,7 +66,7 @@ def __init__(self, user: User):
async def alert(self, msg: str) -> None:
try:
time = datetime.now().strftime(DATE_FORMAT)
alert_msg = f"{time} {self.user.username} {msg}"
alert_msg = f"{time} {self.name} {msg}"
self.log.error(f"Slack Alert: {alert_msg}")
if Configuration.alert_hook == "None":
self.log.info("Alert hook isn't set, so not sending to slack.")
Expand All @@ -80,6 +83,10 @@ async def alert(self, msg: str) -> None:
except Exception:
self.log.exception("Exception thrown while trying to alert!")

def assign_business(self, business: Business) -> None:
self.business = business
business.monkey = self

def logfile(self) -> str:
self._logfile.flush()
return self._logfile.name
Expand Down
18 changes: 10 additions & 8 deletions src/mobu/monkeybusinessfactory.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,16 @@
class MonkeyBusinessFactory:
@staticmethod
def create(body: Dict) -> Monkey:
username = body["username"]
uidnumber = body["uidnumber"]
business = body.get("business", None)
restart = body.get("restart", False)
name = body["name"]
business = body["business"]
user = body["user"]
options = body.get("options", {})

username = user["username"]
uidnumber = user["uidnumber"]

u = User(username, uidnumber)
m = Monkey(u)
m.restart = restart
m = Monkey(name, u, options)

businesses = [
Business,
Expand All @@ -39,10 +41,10 @@ def create(body: Dict) -> Monkey:

for b in businesses:
if business == b.__name__:
new_business = b(m)
new_business = b(m, options)

if not new_business:
raise ValueError(f"Unknown business {business}")

m.business = new_business
m.assign_business(new_business)
return m
13 changes: 7 additions & 6 deletions src/mobu/monkeybusinessmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,19 @@ async def init(self, app: web.Application) -> None:
async def cleanup(self, app: web.Application) -> None:
await self._scheduler.close()

def fetch_monkey(self, username: str) -> Monkey:
return self._monkeys[username]
def fetch_monkey(self, name: str) -> Monkey:
return self._monkeys[name]

def list_monkeys(self) -> List[str]:
return list(self._monkeys.keys())

async def manage_monkey(self, monkey: Monkey) -> None:
self._monkeys[monkey.user.username] = monkey
await self.release_monkey(monkey.name)
self._monkeys[monkey.name] = monkey
await monkey.start(self._scheduler)

async def release_monkey(self, username: str) -> None:
monkey = self._monkeys.get(username, None)
async def release_monkey(self, name: str) -> None:
monkey = self._monkeys.get(name, None)
if monkey is not None:
await monkey.stop()
del self._monkeys[username]
del self._monkeys[name]
4 changes: 3 additions & 1 deletion src/mobu/notebookrunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ async def run(self) -> None:
try:
logger = self.monkey.log

self._client = JupyterClient(self.monkey.user, logger)
self._client = JupyterClient(
self.monkey.user, logger, self.options
)

if not self._repo:
self._repo = git.Repo.clone_from(
Expand Down

0 comments on commit f278b10

Please sign in to comment.