Skip to content

Commit 2107810

Browse files
authored
Merge pull request #100 from yuvipanda/rsession-merge
Bring in https://github.com/jupyterhub/jupyter-rsession-proxy
2 parents ffaae66 + 4413748 commit 2107810

File tree

8 files changed

+248
-0
lines changed

8 files changed

+248
-0
lines changed

contrib/rstudio/Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM jupyter/r-notebook
2+
3+
USER root
4+
5+
RUN apt-get update && \
6+
apt-get install -y --no-install-recommends \
7+
libapparmor1 \
8+
libedit2 \
9+
lsb-release \
10+
psmisc \
11+
libssl1.0.0 \
12+
;
13+
14+
# You can use rsession from rstudio's desktop package as well.
15+
ENV RSTUDIO_PKG=rstudio-server-1.0.136-amd64.deb
16+
17+
RUN wget -q http://download2.rstudio.org/${RSTUDIO_PKG}
18+
RUN dpkg -i ${RSTUDIO_PKG}
19+
RUN rm ${RSTUDIO_PKG}
20+
21+
RUN apt-get clean && \
22+
rm -rf /var/lib/apt/lists/*
23+
24+
USER $NB_USER
25+
26+
RUN pip install git+https://github.com/jupyterhub/jupyter-rsession-proxy
27+
28+
# The desktop package uses /usr/lib/rstudio/bin
29+
ENV PATH="${PATH}:/usr/lib/rstudio-server/bin"
30+
ENV LD_LIBRARY_PATH="/usr/lib/R/lib:/lib:/usr/lib/x86_64-linux-gnu:/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/amd64/server:/opt/conda/lib/R/lib"

contrib/rstudio/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# jupyter-rsession-proxy
2+
3+
**jupyter-rsession-proxy** provides Jupyter server and notebook extensions to proxy RStudio.
4+
5+
![Screenshot](screenshot.png)
6+
7+
If you have a JupyterHub deployment, jupyter-rsession-proxy can take advantage of JupyterHub's existing authenticator and spawner to launch RStudio in users' Jupyter environments. You can also run this from within Jupyter.
8+
Note that [RStudio Server Pro](https://www.rstudio.com/products/rstudio-server-pro/architecture) has more featureful authentication and spawning than the standard version, in the event that you do not want to use Jupyter's.
9+
10+
## Installation
11+
12+
### Pre-reqs
13+
14+
#### Install rstudio
15+
Use conda `conda install rstudio` or [download](https://www.rstudio.com/products/rstudio/download-server/) the corresponding package for your platform
16+
17+
Note that rstudio server is needed to work with this extension.
18+
19+
### Install jupyter-rsession-proxy
20+
21+
Install the library:
22+
```
23+
pip install jupyter-rsession-proxy
24+
```
25+
26+
The Dockerfile contains an example installation on top of [jupyter/r-notebook](https://github.com/jupyter/docker-stacks/tree/master/r-notebook).
27+
28+
29+
### Multiuser Considerations
30+
31+
This extension launches an rstudio server process from the jupyter notebook server. This is fine in JupyterHub deployments where user servers are containerized since other users cannot connect to the rstudio server port. In non-containerized JupyterHub deployments, for example on multiuser systems running LocalSpawner or BatchSpawner, this not secure. Any user may connect to rstudio server and run arbitrary code.
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import os
2+
import tempfile
3+
import subprocess
4+
import getpass
5+
import shutil
6+
from textwrap import dedent
7+
8+
def setup_shiny():
9+
'''Manage a Shiny instance.'''
10+
11+
name = 'shiny'
12+
def _get_shiny_cmd(port):
13+
conf = dedent("""
14+
run_as {user};
15+
server {{
16+
listen {port};
17+
location / {{
18+
site_dir {site_dir};
19+
log_dir {site_dir}/logs;
20+
directory_index on;
21+
}}
22+
}}
23+
""").format(
24+
user=getpass.getuser(),
25+
port=str(port),
26+
site_dir=os.getcwd()
27+
)
28+
29+
f = tempfile.NamedTemporaryFile(mode='w', delete=False)
30+
f.write(conf)
31+
f.close()
32+
return ['shiny-server', f.name]
33+
34+
return {
35+
'command': _get_shiny_cmd,
36+
'launcher_entry': {
37+
'title': 'Shiny',
38+
'icon_path': os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icons', 'shiny.svg')
39+
}
40+
}
41+
42+
def setup_rstudio():
43+
def _get_rsession_env(port):
44+
# Detect various environment variables rsession requires to run
45+
# Via rstudio's src/cpp/core/r_util/REnvironmentPosix.cpp
46+
cmd = ['R', '--slave', '--vanilla', '-e',
47+
'cat(paste(R.home("home"),R.home("share"),R.home("include"),R.home("doc"),getRversion(),sep=":"))']
48+
49+
r_output = subprocess.check_output(cmd)
50+
R_HOME, R_SHARE_DIR, R_INCLUDE_DIR, R_DOC_DIR, version = \
51+
r_output.decode().split(':')
52+
53+
return {
54+
'R_DOC_DIR': R_DOC_DIR,
55+
'R_HOME': R_HOME,
56+
'R_INCLUDE_DIR': R_INCLUDE_DIR,
57+
'R_SHARE_DIR': R_SHARE_DIR,
58+
'RSTUDIO_DEFAULT_R_VERSION_HOME': R_HOME,
59+
'RSTUDIO_DEFAULT_R_VERSION': version,
60+
}
61+
62+
def _get_rsession_cmd(port):
63+
# Other paths rsession maybe in
64+
other_paths = [
65+
# When rstudio-server deb is installed
66+
'/usr/lib/rstudio-server/bin/rsession',
67+
# When just rstudio deb is installed
68+
'/usr/lib/rstudio/bin/rsession',
69+
]
70+
if shutil.which('rsession'):
71+
executable = 'rsession'
72+
else:
73+
for op in other_paths:
74+
if os.path.exists(op):
75+
executable = op
76+
break
77+
else:
78+
raise FileNotFoundError('Can not find rsession in PATH')
79+
80+
return [
81+
executable,
82+
'--standalone=1',
83+
'--program-mode=server',
84+
'--log-stderr=1',
85+
'--session-timeout-minutes=0',
86+
'--user-identity=' + getpass.getuser(),
87+
'--www-port=' + str(port)
88+
]
89+
90+
return {
91+
'command': _get_rsession_cmd,
92+
'environment': _get_rsession_env,
93+
'launcher_entry': {
94+
'title': 'RStudio',
95+
'icon_path': os.path.join(os.path.dirname(os.path.abspath(__file__)), 'icons', 'rstudio.svg')
96+
}
97+
}
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 65 additions & 0 deletions
Loading

contrib/rstudio/screenshot.png

24.9 KB
Loading

contrib/rstudio/setup.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import setuptools
2+
3+
setuptools.setup(
4+
name="jupyter-rsession-proxy",
5+
version='1.0dev',
6+
url="https://github.com/jupyterhub/jupyter-rsession-proxy",
7+
author="Ryan Lovett & Yuvi Panda",
8+
description="Jupyter extension to proxy RStudio's rsession",
9+
packages=setuptools.find_packages(),
10+
keywords=['Jupyter'],
11+
classifiers=['Framework :: Jupyter'],
12+
install_requires=[
13+
'jupyter-server-proxy'
14+
],
15+
entry_points={
16+
'jupyter_serverproxy_servers': [
17+
'rstudio = jupyter_rsession_proxy:setup_rstudio',
18+
'shiny = jupyter_rsession_proxy:setup_shiny'
19+
]
20+
},
21+
package_data={
22+
'jupyter_rsession_proxy': ['icons/*'],
23+
},
24+
)

screenshot.png

24.9 KB
Loading

0 commit comments

Comments
 (0)