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 | ||||
| # 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="*") | ||||
|  | ||||
| @ -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)) | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user