Add /recipes/list route and tests
Includes adding a lock for access to the git repo from the API.
This commit is contained in:
parent
90a8798f4c
commit
b6fb22133c
@ -14,15 +14,17 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
from collections import namedtuple
|
||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
|
||||||
from pylorax.api.crossdomain import crossdomain
|
from pylorax.api.crossdomain import crossdomain
|
||||||
from pylorax.api.v0 import v0_api
|
from pylorax.api.v0 import v0_api
|
||||||
|
|
||||||
|
GitLock = namedtuple("GitLock", ["repo", "lock", "dir"])
|
||||||
|
|
||||||
server = Flask(__name__)
|
server = Flask(__name__)
|
||||||
|
|
||||||
__all__ = ["server"]
|
__all__ = ["server", "GitLock"]
|
||||||
|
|
||||||
@server.route('/')
|
@server.route('/')
|
||||||
@crossdomain(origin="*")
|
@crossdomain(origin="*")
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# 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
|
# Use pykickstart to calculate disk image size
|
||||||
from pykickstart.parser import KickstartParser
|
from pykickstart.parser import KickstartParser
|
||||||
from pykickstart.version import makeVersion, RHEL7
|
from pykickstart.version import makeVersion, RHEL7
|
||||||
|
|
||||||
from pylorax.api.crossdomain import crossdomain
|
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 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_appliance, make_image, make_livecd, make_live_images
|
||||||
from pylorax.creator import make_runtime, make_squashfs
|
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.installer import InstallError
|
||||||
from pylorax.sysutils import joinpaths
|
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
|
# no-virt mode doesn't need libvirt, so make it optional
|
||||||
try:
|
try:
|
||||||
@ -42,3 +45,18 @@ def v0_api(api):
|
|||||||
@crossdomain(origin="*")
|
@crossdomain(origin="*")
|
||||||
def v0_status():
|
def v0_status():
|
||||||
return jsonify(build="devel", api="0", db_version="0", schema_version="0", db_supported=False)
|
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))
|
||||||
|
@ -25,10 +25,12 @@ pylorax_log = logging.getLogger("pylorax")
|
|||||||
import argparse
|
import argparse
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
from threading import Lock
|
||||||
from gevent.wsgi import WSGIServer
|
from gevent.wsgi import WSGIServer
|
||||||
|
|
||||||
from pylorax import vernum
|
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)
|
VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum)
|
||||||
|
|
||||||
@ -105,6 +107,14 @@ if __name__ == '__main__':
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
setup_logging(opts.logfile)
|
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)
|
http_server = WSGIServer((opts.host, opts.port), server)
|
||||||
# The server writes directly to a file object, so point to our log directory
|
# 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"
|
server_logfile = os.path.abspath(os.path.dirname(opts.logfile))+"/server.log"
|
||||||
|
@ -14,20 +14,30 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import os
|
import tempfile
|
||||||
|
from threading import Lock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from flask import json
|
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):
|
class ServerTestCase(unittest.TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(self):
|
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
|
server.config['TESTING'] = True
|
||||||
self.server = server.test_client()
|
self.server = server.test_client()
|
||||||
|
|
||||||
|
# Import the example recipes
|
||||||
|
commit_recipe_directory(server.config["GITLOCK"].repo, "master", "tests/pylorax/recipes/")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(self):
|
def tearDownClass(self):
|
||||||
pass
|
pass
|
||||||
@ -38,3 +48,11 @@ class ServerTestCase(unittest.TestCase):
|
|||||||
resp = self.server.get("/api/v0/status")
|
resp = self.server.get("/api/v0/status")
|
||||||
data = json.loads(resp.data)
|
data = json.loads(resp.data)
|
||||||
self.assertEqual(data, status_dict)
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user