Skip to content

Commit 6790e61

Browse files
committed
feat: added renku service with cache and datasets
1 parent 86fedaf commit 6790e61

34 files changed

+2625
-82
lines changed

.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
REDIS_HOST=redis
2+
REDIS_PORT=6379
3+
REDIS_DATABASE=0
4+
REDIS_PASSWORD=

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,5 @@ target/
7373
renku-*.bottle.json
7474
renku-*.bottle.tar.gz
7575
renku.rb
76+
77+
.env

Dockerfile renamed to Dockerfile.cli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM python:3.6-alpine as base
1+
FROM python:3.7-alpine as base
22

33
RUN apk add --no-cache git && \
44
pip install --no-cache --upgrade pip

Dockerfile.svc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
FROM python:3.7-alpine
2+
3+
RUN apk add --update --no-cache alpine-sdk g++ gcc linux-headers libxslt-dev python3-dev build-base openssl-dev libffi-dev git && \
4+
pip install --no-cache --upgrade pip setuptools pipenv requirements-builder
5+
6+
RUN apk add --no-cache --allow-untrusted \
7+
--repository http://dl-cdn.alpinelinux.org/alpine/latest-stable/community \
8+
--repository http://dl-cdn.alpinelinux.org/alpine/latest-stable/main \
9+
--repository http://nl.alpinelinux.org/alpine/edge/community \
10+
git-lfs && \
11+
git lfs install
12+
13+
COPY . /code/renku
14+
WORKDIR /code/renku
15+
RUN requirements-builder -e all --level=pypi setup.py > requirements.txt && pip install -r requirements.txt && pip install -e . && pip install gunicorn
16+
17+
18+
ENTRYPOINT ["gunicorn", "renku.service.entrypoint:app", "-b", "0.0.0.0:8080"]

MANIFEST.in

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,17 @@
1717
# limitations under the License.
1818

1919
# Check manifest will not automatically add these two files:
20+
include renku/service/.env-example
2021
include .dockerignore
2122
include .editorconfig
2223
include .tx/config
2324
include *.md
2425
prune docs/_build
2526
recursive-include renku *.po *.pot *.mo
26-
27+
recursive-include renku *.py
2728
# added by check_manifest.py
2829
include *.py
30+
include *.yml
2931
include *.rst
3032
include *.sh
3133
include *.txt
@@ -39,6 +41,7 @@ include babel.ini
3941
include brew.py
4042
include pytest.ini
4143
include snap/snapcraft.yaml
44+
recursive-include renku *.json
4245
recursive-include .github CODEOWNERS
4346
recursive-include .travis *.sh
4447
recursive-include docs *.bat
@@ -59,3 +62,4 @@ recursive-include renku *.yml
5962
recursive-include renku Dockerfile
6063
recursive-include tests *.py *.gz *.yml
6164
prune .github
65+
prune .env

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,6 @@ brew-commit-bottle: *.bottle.json
6969

7070
brew-release:
7171
open "https://github.com/SwissDataScienceCenter/renku-python/releases/new?tag=v$(shell brew info --json=v1 renku | jq -r '.[0].versions.stable')"
72+
73+
service-container:
74+
docker build -f Dockerfile.svc -t renku-svc .

Pipfile.lock

Lines changed: 124 additions & 74 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

conftest.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,19 @@
2525
import tempfile
2626
import time
2727
import urllib
28+
import uuid
2829
from pathlib import Path
2930

31+
import fakeredis
3032
import pytest
3133
import responses
3234
import yaml
3335
from click.testing import CliRunner
3436

37+
from renku.core.utils.contexts import chdir
38+
from renku.service.cache import ServiceCache
39+
from renku.service.entrypoint import create_app
40+
3541

3642
@pytest.fixture(scope='module')
3743
def renku_path(tmpdir_factory):
@@ -510,3 +516,86 @@ def remote_project(data_repository, directory_tree):
510516
assert 0 == result.exit_code
511517

512518
yield runner, project_path
519+
520+
521+
@pytest.fixture(scope='function')
522+
def dummy_datapack():
523+
"""Creates dummy data folder."""
524+
temp_dir = tempfile.TemporaryDirectory()
525+
526+
data_file_txt = Path(temp_dir.name) / Path('file.txt')
527+
data_file_txt.write_text('my awesome data')
528+
529+
data_file_csv = Path(temp_dir.name) / Path('file.csv')
530+
data_file_csv.write_text('more,awesome,data')
531+
532+
yield temp_dir
533+
534+
535+
@pytest.fixture(scope='function')
536+
def datapack_zip(dummy_datapack):
537+
"""Returns dummy data folder as a zip archive."""
538+
workspace_dir = tempfile.TemporaryDirectory()
539+
with chdir(workspace_dir.name):
540+
shutil.make_archive('datapack', 'zip', dummy_datapack.name)
541+
542+
yield Path(workspace_dir.name) / 'datapack.zip'
543+
544+
545+
@pytest.fixture(scope='function')
546+
def datapack_tar(dummy_datapack):
547+
"""Returns dummy data folder as a tar archive."""
548+
workspace_dir = tempfile.TemporaryDirectory()
549+
with chdir(workspace_dir.name):
550+
shutil.make_archive('datapack', 'tar', dummy_datapack.name)
551+
552+
yield Path(workspace_dir.name) / 'datapack.tar'
553+
554+
555+
@pytest.fixture(scope='function')
556+
def mock_redis(monkeypatch):
557+
"""Monkey patch service cache with mocked redis."""
558+
with monkeypatch.context() as m:
559+
m.setattr(ServiceCache, 'cache', fakeredis.FakeRedis())
560+
yield
561+
562+
563+
@pytest.fixture(scope='function')
564+
def svc_client(mock_redis):
565+
"""Renku service client."""
566+
flask_app = create_app()
567+
568+
testing_client = flask_app.test_client()
569+
testing_client.testing = True
570+
571+
ctx = flask_app.app_context()
572+
ctx.push()
573+
574+
yield testing_client
575+
576+
ctx.pop()
577+
578+
579+
@pytest.fixture(scope='function')
580+
def svc_client_with_repo(svc_client, mock_redis):
581+
"""Renku service remote repository."""
582+
remote_url = 'https://renkulab.io/gitlab/contact/integration-tests.git'
583+
headers = {'Authorization': 'Bearer b4b4de0eda0f471ab82702bd5c367fa7'}
584+
585+
params = {
586+
'git_url': remote_url,
587+
'git_username': 'contact',
588+
'git_access_token': 'EcfPJvEqjJepyu6XyqKZ',
589+
}
590+
591+
response = svc_client.post(
592+
'/cache/project-clone', data=params, headers=headers
593+
)
594+
595+
assert response
596+
assert 'result' in response.json
597+
assert 'error' not in response.json
598+
project_id = response.json['result']['project_id']
599+
assert isinstance(uuid.UUID(project_id), uuid.UUID)
600+
601+
yield svc_client, headers, project_id

docker-compose.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: '3'
2+
3+
services:
4+
redis:
5+
image: redis:5.0.3-alpine
6+
ports:
7+
- "6379:6379"
8+
9+
renku-svc:
10+
image: renku-svc:latest
11+
env_file: .env
12+
ports:
13+
- "8080:8080"

renku/core/commands/client.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import yaml
2626

2727
from renku.core.management import LocalClient
28+
from renku.core.management.config import RENKU_HOME
29+
from renku.core.management.repository import default_path
2830

2931
from .git import get_git_isolation
3032

@@ -63,8 +65,17 @@ def pass_local_client(
6365
)
6466

6567
def new_func(*args, **kwargs):
66-
ctx = click.get_current_context()
67-
client = ctx.ensure_object(LocalClient)
68+
ctx = click.get_current_context(silent=True)
69+
if not ctx:
70+
client = LocalClient(
71+
path=default_path(),
72+
renku_home=RENKU_HOME,
73+
use_external_storage=True,
74+
)
75+
ctx = click.Context(click.Command(method))
76+
else:
77+
client = ctx.ensure_object(LocalClient)
78+
6879
stack = contextlib.ExitStack()
6980

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

88-
with stack:
89-
result = ctx.invoke(method, client, *args, **kwargs)
99+
result = None
100+
if ctx:
101+
with stack:
102+
result = ctx.invoke(method, client, *args, **kwargs)
103+
90104
return result
91105

92106
return functools.update_wrapper(new_func, method)

0 commit comments

Comments
 (0)