diff --git a/src/pylorax/api/server.py b/src/pylorax/api/server.py
index 044e78c2..3eca9df3 100644
--- a/src/pylorax/api/server.py
+++ b/src/pylorax/api/server.py
@@ -14,15 +14,17 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
-
+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="*")
diff --git a/src/pylorax/api/v0.py b/src/pylorax/api/v0.py
index 2b4b3d5a..ff33a053 100644
--- a/src/pylorax/api/v0.py
+++ b/src/pylorax/api/v0.py
@@ -14,13 +14,14 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
-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))
diff --git a/src/sbin/lorax-composer b/src/sbin/lorax-composer
index 222c76f7..27806cd8 100755
--- a/src/sbin/lorax-composer
+++ b/src/sbin/lorax-composer
@@ -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"
diff --git a/tests/pylorax/test_server.py b/tests/pylorax/test_server.py
index a6b5f539..cb9197dd 100644
--- a/tests/pylorax/test_server.py
+++ b/tests/pylorax/test_server.py
@@ -14,20 +14,30 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
-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)