kopia lustrzana https://github.com/jupyterhub/repo2docker
commit
a0e4dff37f
|
@ -70,3 +70,31 @@ or similar traditional docker command.
|
|||
|
||||
Check out the [binder-examples](http://github.com/binder-examples/) GitHub
|
||||
organization for example repositories you can copy & modify for your own use!
|
||||
|
||||
## Can I use repo2docker to edit a local repository within a Docker environment?
|
||||
|
||||
Yes: use the `--editable` or `-E` flag (don't confuse it with the `-e`
|
||||
flag for environment variables), and run repo2docker on a local
|
||||
repository: `repo2docker -E my-repository/.`.
|
||||
|
||||
This builds a Docker container from the files in that repository
|
||||
(using, for example, a `requirements.txt` file or `Dockerfile`), then
|
||||
runs that container, while connecting the home directory inside the
|
||||
container to the local repository outside the container. For example,
|
||||
in case there is a notebook file (`.ipynb`), this will open in a local
|
||||
webbrowser, and one can edit it and save it. The resulting notebook is
|
||||
updated in both the Docker container and the local repository. Once
|
||||
the container is exited, the changed file will still be in the local
|
||||
repository.
|
||||
|
||||
This allows for easy testing of the container while debugging some
|
||||
items, as well as using a fully customizable container to edit, for
|
||||
example, notebooks.
|
||||
|
||||
**note**
|
||||
|
||||
Editable mode is a convenience option that will mount the repository
|
||||
to container working directory (usually `/home/$USER`). If you need to
|
||||
mount to a different location in the container, use the `--volumes`
|
||||
option instead. Similarly, for a fully customized user Dockerfile,
|
||||
this option is not guaranteed to work.
|
||||
|
|
|
@ -342,6 +342,13 @@ class Repo2Docker(Application):
|
|||
default=[]
|
||||
)
|
||||
|
||||
argparser.add_argument(
|
||||
'--editable', '-E',
|
||||
dest='editable',
|
||||
action='store_true',
|
||||
help='Use the local repository in edit mode',
|
||||
)
|
||||
|
||||
argparser.add_argument(
|
||||
'--appendix',
|
||||
type=str,
|
||||
|
@ -392,6 +399,8 @@ class Repo2Docker(Application):
|
|||
self.repo = args.repo
|
||||
self.ref = None
|
||||
self.cleanup_checkout = False
|
||||
if args.editable:
|
||||
self.volumes[os.path.abspath(args.repo)] = '.'
|
||||
else:
|
||||
self.repo_type = 'remote'
|
||||
self.repo = args.repo
|
||||
|
|
|
@ -68,6 +68,14 @@ def make_test_func(args):
|
|||
return test
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def run_repo2docker():
|
||||
def run_test(args):
|
||||
return make_test_func(args)()
|
||||
return run_test
|
||||
|
||||
|
||||
|
||||
class Repo2DockerTest(pytest.Function):
|
||||
"""A pytest.Item for running repo2docker"""
|
||||
def __init__(self, name, parent, args):
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
FROM python:3.5
|
||||
|
||||
RUN pip install --no-cache notebook
|
||||
|
||||
CMD "/bin/sh"
|
||||
|
||||
ADD change.sh /usr/local/bin/change.sh
|
||||
|
||||
ARG NB_UID
|
||||
ENV HOME /tmp
|
||||
WORKDIR ${HOME}
|
||||
|
||||
USER $NB_UID
|
|
@ -0,0 +1,19 @@
|
|||
Docker - Edit mode
|
||||
------------------
|
||||
|
||||
Using the --editable option with a local repository, one can modify a
|
||||
file or create a new file in the container, and this change is
|
||||
reflected in the respective host directory. It is essentially a
|
||||
shortcut for `--mount
|
||||
type=bind,source=<local-host-repository>,target=.` (where the target
|
||||
resolves into the container working directory).
|
||||
|
||||
This is tested by running the change.sh script inside the container
|
||||
(using the 'cmd' argument to the Repo2Docker app), which creates a new
|
||||
file, and then verifying on the host side the new file is created with
|
||||
the proper contents.
|
||||
|
||||
In practice, this can be used to run a notebook from inside a
|
||||
container (which provides the proper environment), making changes as
|
||||
necessary, which are then immediately reflected in the host
|
||||
repository.
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
cat <<EOF > newfile
|
||||
new contents
|
||||
EOF
|
||||
exit 0
|
|
@ -0,0 +1,56 @@
|
|||
import os
|
||||
import time
|
||||
import re
|
||||
import tempfile
|
||||
from conftest import make_test_func
|
||||
from repo2docker.app import Repo2Docker
|
||||
|
||||
|
||||
DIR = os.path.join(os.path.dirname(__file__), 'dockerfile', 'editable')
|
||||
|
||||
|
||||
def test_editable(run_repo2docker):
|
||||
"""Run a local repository in edit mode. Verify a new file has been
|
||||
created afterwards"""
|
||||
newfile = os.path.join(DIR, 'newfile')
|
||||
try:
|
||||
# If the file didn't get properly cleaned up last time, we
|
||||
# need to do that now
|
||||
os.remove(newfile)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
argv = ['--editable', DIR, '/usr/local/bin/change.sh']
|
||||
run_repo2docker(argv)
|
||||
try:
|
||||
with open(newfile) as fp:
|
||||
contents = fp.read()
|
||||
assert contents == "new contents\n"
|
||||
finally:
|
||||
os.remove(newfile)
|
||||
|
||||
|
||||
def test_editable_by_host():
|
||||
"""Test whether a new file created by the host environment, is
|
||||
detected in the container"""
|
||||
|
||||
app = Repo2Docker()
|
||||
app.initialize(['--editable', DIR])
|
||||
app.run = False
|
||||
app.start() # This just build the image and does not run it.
|
||||
container = app.start_container()
|
||||
# give the container a chance to start
|
||||
time.sleep(1)
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(dir=DIR, prefix='testfile', suffix='.txt'):
|
||||
status, output = container.exec_run(['sh', '-c', 'ls testfile????????.txt'])
|
||||
assert status == 0
|
||||
assert re.match(br'^testfile\w{8}\.txt\n$', output) is not None
|
||||
# File should be removed in the container as well
|
||||
status, output = container.exec_run(['sh', '-c', 'ls testfile????????.txt'])
|
||||
assert status != 1
|
||||
assert re.match(br'^testfile\w{8}\.txt\n$', output) is None
|
||||
|
||||
finally:
|
||||
# stop the container
|
||||
container.stop()
|
||||
app.wait_for_container(container)
|
Ładowanie…
Reference in New Issue