Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the report using the Tern #3

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[run]
omit = *tests*,app.py
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
tests/
docs/
cached/
.github
.gitignore
Dockerfile
Makefile
Pipfile
Pipfile.lock
README.md
requirements-dev.txt
setup.py
tox.ini
.coverage
.dockerignore
.git
.mypy_cache
.pytest_cache
.tox
__pycache__
tern_rest_api.egg-info
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ jobs:
run: pip install tox tox-gh-actions

- name: Run Python tests
run: tox
run: tox -r
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# tern-rest-api specifics
cached
docs/.test_swagger.json
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2022 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: BSD-2-Clause

FROM python:3.9-slim-buster as base

RUN echo "deb http://deb.debian.org/debian bullseye main" > /etc/apt/sources.list.d/bullseye.list \
&& echo "Package: *\nPin: release n=bullseye\nPin-Priority: 50" > /etc/apt/preferences.d/bullseye \
&& apt-get update \
&& apt-get install -y --no-install-recommends \
attr \
findutils \
fuse-overlayfs/bullseye \
fuse3/bullseye \
git \
jq \
skopeo \
&& rm -rf /var/lib/apt/lists/*

COPY requirements.txt requirements.txt
RUN pip install --no-cache -r ./requirements.txt

RUN mkdir /opt/tern-rest-api

ADD . /opt/tern-rest-api
WORKDIR /opt/tern-rest-api

ENV TERN_API_CACHE_DIR=/var/opt/tern-rest-api/cache
ENV TERN_DEFAULT_REGISTRY="registry.hub.docker.com"

ENTRYPOINT [ "bash", "docker_start.sh" ]
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (c) 2022 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: BSD-2-Clause

build-dev:
docker-compose build --force-rm tern-rest-api

serve-dev: build-dev
docker-compose up --remove-orphans

tests: build-dev
docker-compose run --rm --volume=$(PWD):/opt/tern-rest-api --entrypoint="/bin/sh" tern-rest-api -c 'pip install tox && tox'

stop:
docker-compose down -v

update-requirements:
pipenv lock -r > requirements.txt
pipenv lock -r -d > requirements-dev.txt

doc:
python -c "import app; app.export_swagger_json('docs/swagger.json')"
2 changes: 2 additions & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ name = "pypi"
flask = "*"
flask-restx = "*"
tern = "*"
flask-executor = "*"
gunicorn = "*"

[dev-packages]
black = "*"
Expand Down
253 changes: 120 additions & 133 deletions Pipfile.lock

Large diffs are not rendered by default.

45 changes: 38 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ files to help build your virtual environment.
We also recommend using [Pipenv](https://pipenv.pypa.io/en/latest/) to manage your virtual environment.

```shell
$ Pip install pipenv
$ pip install pipenv
$ pipenv shell
```

Expand All @@ -59,7 +59,26 @@ $ pipenv install -d

### Running the development Tern REST API

#### As a Docker Container
```shell
$ make serve-dev
```
Open http://localhost/ in your browser.

Changing the source code will automatically reload the server inside the
container and makes the development easier.

You can stop the sever using ``Ctrl+C`` and running ``make stop``

Container environment variables:

- ``TERN_API_CACHE_DIR``: The directory where the tern reports are cached.
Default: ``/var/opt/tern-rest-api/cache``
- ``TERN_DEFAULT_REGISTRY``: Optional default registry to use when no registry
is passed to the API requests. Default: ``docker.io``


#### On your local machine
Runing the API locally

```shell
Expand All @@ -68,16 +87,29 @@ $ flask run --reload

Open http://localhost:5000/ in your browser.

## Tests
### Tests

We use [Tox](https://tox.wiki/en/latest/) to manage running the tests.

Running tests
#### As a Docker Container
```shell
$ make tests
```

#### On your local machine
```shell
$ tox
```

## Managing the requirements
### Documentation

```shell
$ make doc
```

The documentation tests are done also by ``tox``.

### Requirements

Installing new requirements

Expand All @@ -97,6 +129,5 @@ $ pipenv update

Updating the ``requirements.txt`` and ``requirements-dev.txt``
```shell
$ pipenv lock -r > requirements.txt
$ pipenv lock -r -d > requirements-dev.txt
```
$ make update-requirements
```
13 changes: 7 additions & 6 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@

from flask_restx import Api

from tern_api import __version__, tern_api
from tern_api import __version__, tern_app
from tern_api.api.v1.common_models import api_models_namespace
from tern_api.api.v1.reports import ns as report_v1
from tern_api.api.v1.reports import ns as reports_v1
from tern_api.api.v1.version import ns as version_v1

logging.basicConfig(
Expand All @@ -26,20 +26,21 @@


api = Api(
tern_api,
tern_app,
version=__version__.version,
title="Tern REST API",
description="Tern Project REST API",
)


api.add_namespace(api_models_namespace)
api.add_namespace(version_v1, path="/api/v1/version")
api.add_namespace(report_v1, path="/api/v1/report")
api.add_namespace(reports_v1, path="/api/v1/reports")


def export_swagger_json(filepath):
tern_api.config["SERVER_NAME"] = "localhost"
with tern_api.app_context().__enter__():
tern_app.config["SERVER_NAME"] = "localhost"
with tern_app.app_context().__enter__():
with open(filepath, "w") as f:
swagger_json = json.dumps(api.__schema__, indent=4)
f.write(swagger_json)
21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
version: '3'

volumes:
tern-cache:

services:
tern-rest-api:
build:
context: .
args:
DEVEL: "yes"
command: "bash bash_start.sh"
environment:
- ENVIRONMENT=development
- TERN_DEFAULT_REGISTRY=registry.hub.docker.com
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- tern-cache:/var/opt/tern-rest-api/cache:z
- ./tern_api:/opt/tern-rest-api/tern_api:z
ports:
- "5001:80"
8 changes: 8 additions & 0 deletions docker_start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

if [[ ${ENVIRONMENT^^} == "DEVELOPMENT" ]]; then
echo "Starting tern-rest-api in development mode"
gunicorn --reload -b 0.0.0.0:80 app:tern_app
else
gunicorn -b 0.0.0.0:80 app:tern_app
fi
57 changes: 45 additions & 12 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"swagger": "2.0",
"basePath": "/",
"paths": {
"/api/v1/report": {
"/api/v1/reports": {
"post": {
"responses": {
"200": {
Expand Down Expand Up @@ -30,7 +30,7 @@
]
}
},
"/api/v1/report/status": {
"/api/v1/reports/status": {
"post": {
"responses": {
"200": {
Expand Down Expand Up @@ -145,15 +145,14 @@
},
"report_parameters": {
"required": [
"cache",
"image",
"tag"
],
"properties": {
"registry": {
"type": "string",
"description": "Registry Server",
"default": "https://registry.hub.docker.com",
"example": "http://registry.example.com"
"description": "Registry Server"
},
"image": {
"type": "string",
Expand All @@ -164,6 +163,11 @@
"type": "string",
"description": "Image tag",
"example": "3.0"
},
"cache": {
"type": "boolean",
"description": "Use cache data if available?",
"example": true
}
},
"type": "object"
Expand All @@ -181,6 +185,7 @@
},
"async_response_model": {
"required": [
"cache",
"id"
],
"properties": {
Expand All @@ -193,6 +198,11 @@
"type": "string",
"description": "Unique Identification for request",
"example": "19f035a711644eab84ef5a38ceb5572e"
},
"cache": {
"type": "boolean",
"description": "Request uses cache?",
"example": true
}
},
"type": "object"
Expand Down Expand Up @@ -220,21 +230,38 @@
},
"data_status_response": {
"required": [
"cache",
"status"
],
"properties": {
"cache": {
"type": "boolean",
"description": "Requested using cache?",
"example": true
},
"id": {
"type": "string",
"description": "Unique Identification for request",
"example": "19f035a711644eab84ef5a38ceb5572e"
},
"message": {
"type": "string",
"description": "Message"
},
"report": {
"$ref": "#/definitions/report_mode"
},
"status": {
"type": "string",
"description": "Status of request",
"example": "DONE",
"example": "SUCCESS",
"enum": [
"UNKNOWN",
"FAILED",
"DONE"
"PENDING",
"RECEIVED",
"RUNNING",
"SUCCESS",
"FAILURE"
]
},
"result": {
"$ref": "#/definitions/report_mode"
}
},
"type": "object"
Expand All @@ -260,6 +287,7 @@
},
"image_report_data": {
"required": [
"cache",
"name",
"repotag",
"tag"
Expand All @@ -276,6 +304,11 @@
"tag": {
"type": "string",
"example": "3.0"
},
"cache": {
"type": "string",
"description": "Use cache if available?",
"default": true
}
},
"type": "object"
Expand Down
Loading