Skip to content

Commit

Permalink
feat: added renku service with cache and datasets
Browse files Browse the repository at this point in the history
  • Loading branch information
jsam committed Dec 3, 2019
1 parent f11edf2 commit d339e66
Show file tree
Hide file tree
Showing 41 changed files with 3,367 additions and 189 deletions.
4 changes: 4 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DATABASE=0
REDIS_PASSWORD=
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,5 @@ target/
renku-*.bottle.json
renku-*.bottle.tar.gz
renku.rb

.env
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ before_install:
- if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
sudo apt-get update;
sudo apt-get -y install shellcheck;
travis_retry python -m pip install --upgrade pip setuptools py;
travis_retry python -m pip install --upgrade six pip setuptools py;
travis_retry python -m pip install twine wheel coveralls requirements-builder;
requirements-builder -e all --level=min setup.py > .travis-lowest-requirements.txt;
requirements-builder -e all --level=pypi setup.py > .travis-release-requirements.txt;
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile → Dockerfile.cli
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.6-alpine as base
FROM python:3.7-alpine as base

RUN apk add --no-cache git && \
pip install --no-cache --upgrade pip
Expand Down
18 changes: 18 additions & 0 deletions Dockerfile.svc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM python:3.7-alpine

RUN apk add --update --no-cache alpine-sdk g++ gcc linux-headers libxslt-dev python3-dev build-base openssl-dev libffi-dev git bash && \
pip install --no-cache --upgrade pip setuptools pipenv requirements-builder

RUN apk add --no-cache --allow-untrusted \
--repository http://dl-cdn.alpinelinux.org/alpine/latest-stable/community \
--repository http://dl-cdn.alpinelinux.org/alpine/latest-stable/main \
--repository http://nl.alpinelinux.org/alpine/edge/community \
git-lfs && \
git lfs install

COPY . /code/renku
WORKDIR /code/renku
RUN requirements-builder -e all --level=pypi setup.py > requirements.txt && pip install -r requirements.txt && pip install -e . && pip install gunicorn


ENTRYPOINT ["gunicorn", "renku.service.entrypoint:app", "-b", "0.0.0.0:8080"]
6 changes: 5 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@
# limitations under the License.

# Check manifest will not automatically add these two files:
include renku/service/.env-example
include .dockerignore
include .editorconfig
include .tx/config
include *.md
prune docs/_build
recursive-include renku *.po *.pot *.mo

recursive-include renku *.py
# added by check_manifest.py
include *.py
include *.yml
include *.rst
include *.sh
include *.txt
Expand All @@ -39,6 +41,7 @@ include babel.ini
include brew.py
include pytest.ini
include snap/snapcraft.yaml
recursive-include renku *.json
recursive-include .github CODEOWNERS
recursive-include .travis *.sh
recursive-include docs *.bat
Expand All @@ -60,3 +63,4 @@ recursive-include renku *.json
recursive-include renku Dockerfile
recursive-include tests *.py *.gz *.yml *.json
prune .github
prune .env
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ brew-commit-bottle: *.bottle.json

brew-release:
open "https://github.com/SwissDataScienceCenter/renku-python/releases/new?tag=v$(shell brew info --json=v1 renku | jq -r '.[0].versions.stable')"

service-container:
docker build -f Dockerfile.svc -t renku-svc:`git rev-parse --short HEAD` .
431 changes: 260 additions & 171 deletions Pipfile.lock

Large diffs are not rendered by default.

175 changes: 175 additions & 0 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import tempfile
import time
import urllib
import uuid
from pathlib import Path

import fakeredis
import pytest
import responses
import yaml
Expand Down Expand Up @@ -510,3 +512,176 @@ def remote_project(data_repository, directory_tree):
assert 0 == result.exit_code

yield runner, project_path


@pytest.fixture(scope='function')
def dummy_datapack():
"""Creates dummy data folder."""
temp_dir = tempfile.TemporaryDirectory()

data_file_txt = Path(temp_dir.name) / Path('file.txt')
data_file_txt.write_text('my awesome data')

data_file_csv = Path(temp_dir.name) / Path('file.csv')
data_file_csv.write_text('more,awesome,data')

yield temp_dir


@pytest.fixture(scope='function')
def datapack_zip(dummy_datapack):
"""Returns dummy data folder as a zip archive."""
from renku.core.utils.contexts import chdir
workspace_dir = tempfile.TemporaryDirectory()
with chdir(workspace_dir.name):
shutil.make_archive('datapack', 'zip', dummy_datapack.name)

yield Path(workspace_dir.name) / 'datapack.zip'


@pytest.fixture(scope='function')
def datapack_tar(dummy_datapack):
"""Returns dummy data folder as a tar archive."""
from renku.core.utils.contexts import chdir
workspace_dir = tempfile.TemporaryDirectory()
with chdir(workspace_dir.name):
shutil.make_archive('datapack', 'tar', dummy_datapack.name)

yield Path(workspace_dir.name) / 'datapack.tar'


@pytest.fixture(scope='function')
def mock_redis(monkeypatch):
"""Monkey patch service cache with mocked redis."""
from renku.service.cache import ServiceCache
with monkeypatch.context() as m:
m.setattr(ServiceCache, 'cache', fakeredis.FakeRedis())
yield


@pytest.fixture(scope='function')
def svc_client(mock_redis):
"""Renku service client."""
from renku.service.entrypoint import create_app

flask_app = create_app()

testing_client = flask_app.test_client()
testing_client.testing = True

ctx = flask_app.app_context()
ctx.push()

yield testing_client

ctx.pop()


@pytest.fixture(scope='function')
def svc_client_with_repo(svc_client, mock_redis):
"""Renku service remote repository."""
remote_url = 'https://dev.renku.ch/gitlab/contact/integration-tests'
headers = {
'Content-Type': 'application/json',
'Renku-User-Id': 'b4b4de0eda0f471ab82702bd5c367fa7',
'Renku-User-FullName': 'Just Sam',
'Renku-User-Email': '[email protected]',
'Authorization': 'Bearer LkoLiyLqnhMCAa4or5qa',
}

payload = {'git_url': remote_url}

response = svc_client.post(
'/cache/project-clone',
data=json.dumps(payload),
headers=headers,
)

assert response
assert 'result' in response.json
assert 'error' not in response.json
project_id = response.json['result']['project_id']
assert isinstance(uuid.UUID(project_id), uuid.UUID)

yield svc_client, headers, project_id


@pytest.fixture(
params=[
{
'url': '/cache/files-list',
'allowed_method': 'GET',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/cache/files-upload',
'allowed_method': 'POST',
'headers': {}
},
{
'url': '/cache/project-clone',
'allowed_method': 'POST',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/cache/project-list',
'allowed_method': 'GET',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/datasets/add',
'allowed_method': 'POST',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/datasets/create',
'allowed_method': 'POST',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/datasets/files-list',
'allowed_method': 'GET',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
{
'url': '/datasets/list',
'allowed_method': 'GET',
'headers': {
'Content-Type': 'application/json',
'accept': 'application/json',
}
},
]
)
def service_allowed_endpoint(request, svc_client, mock_redis):
"""Ensure allowed methods and correct headers."""
methods = {
'GET': svc_client.get,
'POST': svc_client.post,
'HEAD': svc_client.head,
'PUT': svc_client.put,
'DELETE': svc_client.delete,
'OPTIONS': svc_client.options,
'TRACE': svc_client.trace,
'PATCH': svc_client.patch,
}

yield methods, request.param, svc_client
13 changes: 13 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3'

services:
redis:
image: redis:5.0.3-alpine
ports:
- "6379:6379"

renku-svc:
image: renku-svc:latest
env_file: .env
ports:
- "8080:8080"
2 changes: 1 addition & 1 deletion renku/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
option_use_external_storage
from renku.core.commands.version import check_version, print_version
from renku.core.management.client import LocalClient
from renku.core.management.config import ConfigManagerMixin, RENKU_HOME
from renku.core.management.config import RENKU_HOME, ConfigManagerMixin
from renku.core.management.repository import default_path

#: Monkeypatch Click application.
Expand Down
22 changes: 18 additions & 4 deletions renku/core/commands/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import yaml

from renku.core.management import LocalClient
from renku.core.management.config import RENKU_HOME
from renku.core.management.repository import default_path

from .git import get_git_isolation

Expand Down Expand Up @@ -63,8 +65,17 @@ def pass_local_client(
)

def new_func(*args, **kwargs):
ctx = click.get_current_context()
client = ctx.ensure_object(LocalClient)
ctx = click.get_current_context(silent=True)
if not ctx:
client = LocalClient(
path=default_path(),
renku_home=RENKU_HOME,
use_external_storage=True,
)
ctx = click.Context(click.Command(method))
else:
client = ctx.ensure_object(LocalClient)

stack = contextlib.ExitStack()

# Handle --isolation option:
Expand All @@ -85,8 +96,11 @@ def new_func(*args, **kwargs):
if lock or (lock is None and commit):
stack.enter_context(client.lock)

with stack:
result = ctx.invoke(method, client, *args, **kwargs)
result = None
if ctx:
with stack:
result = ctx.invoke(method, client, *args, **kwargs)

return result

return functools.update_wrapper(new_func, method)
12 changes: 10 additions & 2 deletions renku/core/commands/clone.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ def renku_clone(
path=None,
install_githooks=True,
skip_smudge=True,
progress=None
recursive=True,
depth=None,
progress=None,
config=None,
raise_git_except=False
):
"""Clone Renku project repo, install Git hooks and LFS."""
install_lfs = client.use_external_storage
Expand All @@ -39,5 +43,9 @@ def renku_clone(
install_githooks=install_githooks,
install_lfs=install_lfs,
skip_smudge=skip_smudge,
progress=progress
recursive=recursive,
depth=depth,
progress=progress,
config=config,
raise_git_except=raise_git_except,
)
2 changes: 1 addition & 1 deletion renku/core/commands/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ def add_file(
destination='',
ref=None,
with_metadata=None,
urlscontext=contextlib.nullcontext
urlscontext=contextlib.nullcontext,
):
"""Add data file to a dataset."""
add_to_dataset(
Expand Down
Loading

0 comments on commit d339e66

Please sign in to comment.