Add /recipes/list route and tests

Includes adding a lock for access to the git repo from the API.
This commit is contained in:
Brian C. Lane 2017-11-07 17:09:56 -08:00
parent 90a8798f4c
commit b6fb22133c
4 changed files with 54 additions and 6 deletions

View File

@ -14,15 +14,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from collections import namedtuple
from flask import Flask
from pylorax.api.crossdomain import crossdomain
from pylorax.api.v0 import v0_api
GitLock = namedtuple("GitLock", ["repo", "lock", "dir"])
server = Flask(__name__)
__all__ = ["server"]
__all__ = ["server", "GitLock"]
@server.route('/')
@crossdomain(origin="*")

View File

@ -14,13 +14,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from flask import jsonify
from flask import jsonify, request
# Use pykickstart to calculate disk image size
from pykickstart.parser import KickstartParser
from pykickstart.version import makeVersion, RHEL7
from pylorax.api.crossdomain import crossdomain
from pylorax.api.recipes import list_branch_files
from pylorax.creator import DRACUT_DEFAULT, mount_boot_part_over_root
from pylorax.creator import make_appliance, make_image, make_livecd, make_live_images
from pylorax.creator import make_runtime, make_squashfs
@ -29,6 +30,8 @@ from pylorax.imgutils import Mount, PartitionMount, umount
from pylorax.installer import InstallError
from pylorax.sysutils import joinpaths
# The API functions don't actually get called by any code here
# pylint: disable=unused-variable
# no-virt mode doesn't need libvirt, so make it optional
try:
@ -42,3 +45,18 @@ def v0_api(api):
@crossdomain(origin="*")
def v0_status():
return jsonify(build="devel", api="0", db_version="0", schema_version="0", db_supported=False)
@api.route("/api/v0/recipes/list")
@crossdomain(origin="*")
def v0_recipes_list():
"""List the available recipes on a branch."""
try:
limit = int(request.args.get("limit", "20"))
offset = int(request.args.get("offset", "0"))
except ValueError:
# TODO return an error
pass
with api.config["GITLOCK"].lock:
recipes = map(lambda f: f[:-5], list_branch_files(api.config["GITLOCK"].repo, "master"))
return jsonify(recipes=recipes, limit=limit, offset=offset, total=len(recipes))

View File

@ -25,10 +25,12 @@ pylorax_log = logging.getLogger("pylorax")
import argparse
import os
import sys
from threading import Lock
from gevent.wsgi import WSGIServer
from pylorax import vernum
from pylorax.api.server import server
from pylorax.api.recipes import open_or_create_repo, commit_recipe_directory
from pylorax.api.server import server, GitLock
VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
@ -105,6 +107,14 @@ if __name__ == '__main__':
sys.exit(1)
setup_logging(opts.logfile)
server.config["REPO_DIR"] = opts.RECIPES
repo = open_or_create_repo(server.config["REPO_DIR"])
server.config["GITLOCK"] = GitLock(repo=repo, lock=Lock(), dir=opts.RECIPES)
# Import example recipes
commit_recipe_directory(server.config["GITLOCK"].repo, "master", opts.RECIPES)
http_server = WSGIServer((opts.host, opts.port), server)
# The server writes directly to a file object, so point to our log directory
server_logfile = os.path.abspath(os.path.dirname(opts.logfile))+"/server.log"

View File

@ -14,20 +14,30 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os
import tempfile
from threading import Lock
import unittest
from flask import json
from pylorax.api.server import server
from pylorax.api.recipes import open_or_create_repo, commit_recipe_directory
from pylorax.api.server import server, GitLock
class ServerTestCase(unittest.TestCase):
@classmethod
def setUpClass(self):
repo_dir = tempfile.mkdtemp(prefix="lorax.test.repo.")
server.config["REPO_DIR"] = repo_dir
repo = open_or_create_repo(server.config["REPO_DIR"])
server.config["GITLOCK"] = GitLock(repo=repo, lock=Lock(), dir=repo_dir)
server.config['TESTING'] = True
self.server = server.test_client()
# Import the example recipes
commit_recipe_directory(server.config["GITLOCK"].repo, "master", "tests/pylorax/recipes/")
@classmethod
def tearDownClass(self):
pass
@ -38,3 +48,11 @@ class ServerTestCase(unittest.TestCase):
resp = self.server.get("/api/v0/status")
data = json.loads(resp.data)
self.assertEqual(data, status_dict)
def test_recipes_list(self):
"""Test the /api/v0/recipes/list route"""
list_dict = {"recipes":["atlas", "development", "glusterfs", "http-server", "jboss", "kubernetes"],
"limit":20, "offset":0, "total":6}
resp = self.server.get("/api/v0/recipes/list")
data = json.loads(resp.data)
self.assertEqual(data, list_dict)