Add /recipes/info route and tests
This commit is contained in:
parent
b7f651a631
commit
1e7335a506
@ -21,7 +21,8 @@ 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.api.recipes import list_branch_files, read_recipe_commit, recipe_filename
|
||||||
|
from pylorax.api.workspace import workspace_read
|
||||||
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
|
||||||
@ -60,3 +61,52 @@ def v0_api(api):
|
|||||||
with api.config["GITLOCK"].lock:
|
with api.config["GITLOCK"].lock:
|
||||||
recipes = map(lambda f: f[:-5], list_branch_files(api.config["GITLOCK"].repo, "master"))
|
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))
|
return jsonify(recipes=recipes, limit=limit, offset=offset, total=len(recipes))
|
||||||
|
|
||||||
|
@api.route("/api/v0/recipes/info/<recipe_names>")
|
||||||
|
@crossdomain(origin="*")
|
||||||
|
def v0_recipes_info(recipe_names):
|
||||||
|
"""Return the contents of the recipe, or a list of recipes"""
|
||||||
|
recipes = []
|
||||||
|
changes = []
|
||||||
|
errors = []
|
||||||
|
for recipe_name in [n.strip() for n in recipe_names.split(",")]:
|
||||||
|
exceptions = []
|
||||||
|
filename = recipe_filename(recipe_name)
|
||||||
|
# Get the workspace version (if it exists)
|
||||||
|
try:
|
||||||
|
with api.config["GITLOCK"].lock:
|
||||||
|
ws_recipe = workspace_read(api.config["GITLOCK"].repo, "master", filename)
|
||||||
|
except Exception as e:
|
||||||
|
ws_recipe = None
|
||||||
|
exceptions.append(str(e))
|
||||||
|
|
||||||
|
# Get the git version (if it exists)
|
||||||
|
try:
|
||||||
|
with api.config["GITLOCK"].lock:
|
||||||
|
git_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", filename)
|
||||||
|
except Exception as e:
|
||||||
|
git_recipe = None
|
||||||
|
exceptions.append(str(e))
|
||||||
|
|
||||||
|
if not ws_recipe and not git_recipe:
|
||||||
|
# Neither recipe, return an error
|
||||||
|
errors.append({"recipe":recipe_name, "msg":", ".join(exceptions)})
|
||||||
|
elif ws_recipe and not git_recipe:
|
||||||
|
# No git recipe, return the workspace recipe
|
||||||
|
changes.append({"name":recipe_name, "changed":True})
|
||||||
|
recipes.append(ws_recipe)
|
||||||
|
elif not ws_recipe and git_recipe:
|
||||||
|
# No workspace recipe, no change, return the git recipe
|
||||||
|
changes.append({"name":recipe_name, "changed":False})
|
||||||
|
recipes.append(git_recipe)
|
||||||
|
else:
|
||||||
|
# Both exist, maybe changed, return the workspace recipe
|
||||||
|
changes.append({"name":recipe_name, "changed":ws_recipe == git_recipe})
|
||||||
|
recipes.append(ws_recipe)
|
||||||
|
|
||||||
|
# Sort all the results by case-insensitive recipe name
|
||||||
|
changes = sorted(changes, key=lambda c: c["name"].lower())
|
||||||
|
recipes = sorted(recipes, key=lambda r: r["name"].lower())
|
||||||
|
errors = sorted(errors, key=lambda e: e["recipe"].lower())
|
||||||
|
|
||||||
|
return jsonify(changes=changes, recipes=recipes, errors=errors)
|
||||||
|
@ -56,3 +56,56 @@ class ServerTestCase(unittest.TestCase):
|
|||||||
resp = self.server.get("/api/v0/recipes/list")
|
resp = self.server.get("/api/v0/recipes/list")
|
||||||
data = json.loads(resp.data)
|
data = json.loads(resp.data)
|
||||||
self.assertEqual(data, list_dict)
|
self.assertEqual(data, list_dict)
|
||||||
|
|
||||||
|
def test_recipes_info(self):
|
||||||
|
"""Test the /api/v0/recipes/info route"""
|
||||||
|
info_dict_1 = {"changes":[{"changed":False, "name":"http-server"}],
|
||||||
|
"errors":[],
|
||||||
|
"recipes":[{"description":"An example http server with PHP and MySQL support.",
|
||||||
|
"modules":[{"name":"httpd", "version":"2.4.*"},
|
||||||
|
{"name":"mod_auth_kerb", "version":"5.4"},
|
||||||
|
{"name":"mod_ssl", "version":"2.4.*"},
|
||||||
|
{"name":"php", "version":"5.4.*"},
|
||||||
|
{"name": "php-mysql", "version":"5.4.*"}],
|
||||||
|
"name":"http-server",
|
||||||
|
"packages": [{"name":"openssh-server", "version": "6.6.*"},
|
||||||
|
{"name": "rsync", "version": "3.0.*"},
|
||||||
|
{"name": "tmux", "version": "2.2"}],
|
||||||
|
"version": "0.0.2"}]}
|
||||||
|
resp = self.server.get("/api/v0/recipes/info/http-server")
|
||||||
|
data = json.loads(resp.data)
|
||||||
|
self.assertEqual(data, info_dict_1)
|
||||||
|
|
||||||
|
info_dict_2 = {"changes":[{"changed":False, "name":"glusterfs"},
|
||||||
|
{"changed":False, "name":"http-server"}],
|
||||||
|
"errors":[],
|
||||||
|
"recipes":[{"description": "An example GlusterFS server with samba",
|
||||||
|
"modules":[{"name":"glusterfs", "version":"3.7.*"},
|
||||||
|
{"name":"glusterfs-cli", "version":"3.7.*"}],
|
||||||
|
"name":"glusterfs",
|
||||||
|
"packages":[{"name":"samba", "version":"4.2.*"}],
|
||||||
|
"version": "0.0.1"},
|
||||||
|
{"description":"An example http server with PHP and MySQL support.",
|
||||||
|
"modules":[{"name":"httpd", "version":"2.4.*"},
|
||||||
|
{"name":"mod_auth_kerb", "version":"5.4"},
|
||||||
|
{"name":"mod_ssl", "version":"2.4.*"},
|
||||||
|
{"name":"php", "version":"5.4.*"},
|
||||||
|
{"name": "php-mysql", "version":"5.4.*"}],
|
||||||
|
"name":"http-server",
|
||||||
|
"packages": [{"name":"openssh-server", "version": "6.6.*"},
|
||||||
|
{"name": "rsync", "version": "3.0.*"},
|
||||||
|
{"name": "tmux", "version": "2.2"}],
|
||||||
|
"version": "0.0.2"},
|
||||||
|
]}
|
||||||
|
resp = self.server.get("/api/v0/recipes/info/http-server,glusterfs")
|
||||||
|
data = json.loads(resp.data)
|
||||||
|
self.assertEqual(data, info_dict_2)
|
||||||
|
|
||||||
|
info_dict_3 = {"changes":[],
|
||||||
|
"errors":[{"recipe":"missing-recipe", "msg":"ggit-error: the path 'missing-recipe.toml' does not exist in the given tree (-3)"}],
|
||||||
|
"recipes":[]
|
||||||
|
}
|
||||||
|
resp = self.server.get("/api/v0/recipes/info/missing-recipe")
|
||||||
|
data = json.loads(resp.data)
|
||||||
|
self.assertEqual(data, info_dict_3)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user