Add support for other branches to the routes
Passing ?branch=<branch-name> will use the specified branch instead of master. The new branch will not exist until a /recipes/new?branch=new-branch POST is made. At that time the branch will be created based on the current master branch and the new commit will be added to it.
This commit is contained in:
parent
0af072c77e
commit
916a001d73
@ -245,6 +245,14 @@ def write_commit(repo, branch, filename, message, content):
|
||||
:rtype: Git.OId
|
||||
:raises: Can raise errors from Ggit
|
||||
"""
|
||||
try:
|
||||
parent_commit = head_commit(repo, branch)
|
||||
except GLib.GError:
|
||||
# Branch doesn't exist, make a new one based on master
|
||||
master_head = head_commit(repo, "master")
|
||||
repo.create_branch(branch, master_head, 0)
|
||||
parent_commit = head_commit(repo, branch)
|
||||
|
||||
parent_commit = head_commit(repo, branch)
|
||||
blob_id = repo.create_blob_from_buffer(content)
|
||||
|
||||
|
@ -66,6 +66,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_list():
|
||||
"""List the available recipes on a branch."""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
limit = int(request.args.get("limit", "20"))
|
||||
offset = int(request.args.get("offset", "0"))
|
||||
@ -73,13 +74,14 @@ def v0_api(api):
|
||||
return jsonify(error={"msg":str(e)}), 400
|
||||
|
||||
with api.config["GITLOCK"].lock:
|
||||
recipes = take_limits(map(lambda f: f[:-5], list_branch_files(api.config["GITLOCK"].repo, "master")), offset, limit)
|
||||
recipes = take_limits(map(lambda f: f[:-5], list_branch_files(api.config["GITLOCK"].repo, branch)), offset, limit)
|
||||
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"""
|
||||
branch = request.args.get("branch", "master")
|
||||
recipes = []
|
||||
changes = []
|
||||
errors = []
|
||||
@ -88,7 +90,7 @@ def v0_api(api):
|
||||
# Get the workspace version (if it exists)
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
ws_recipe = workspace_read(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
ws_recipe = workspace_read(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
ws_recipe = None
|
||||
exceptions.append(str(e))
|
||||
@ -97,7 +99,7 @@ def v0_api(api):
|
||||
# Get the git version (if it exists)
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
git_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
git_recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
git_recipe = None
|
||||
exceptions.append(str(e))
|
||||
@ -130,6 +132,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_changes(recipe_names):
|
||||
"""Return the changes to a recipe or list of recipes"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
limit = int(request.args.get("limit", "20"))
|
||||
offset = int(request.args.get("offset", "0"))
|
||||
@ -142,7 +145,7 @@ def v0_api(api):
|
||||
filename = recipe_filename(recipe_name)
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
commits = take_limits(list_commits(api.config["GITLOCK"].repo, "master", filename), offset, limit)
|
||||
commits = take_limits(list_commits(api.config["GITLOCK"].repo, branch, filename), offset, limit)
|
||||
except Exception as e:
|
||||
errors.append({"recipe":recipe_name, "msg":e})
|
||||
log.error("(v0_recipes_changes) %s", str(e))
|
||||
@ -158,6 +161,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_new():
|
||||
"""Commit a new recipe"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
if request.headers['Content-Type'] == "text/x-toml":
|
||||
recipe = recipe_from_toml(request.data)
|
||||
@ -165,11 +169,11 @@ def v0_api(api):
|
||||
recipe = recipe_from_dict(request.get_json(cache=False))
|
||||
|
||||
with api.config["GITLOCK"].lock:
|
||||
commit_recipe(api.config["GITLOCK"].repo, "master", recipe)
|
||||
commit_recipe(api.config["GITLOCK"].repo, branch, recipe)
|
||||
|
||||
# Read the recipe with new version and write it to the workspace
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe["name"])
|
||||
workspace_write(api.config["GITLOCK"].repo, "master", recipe)
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe["name"])
|
||||
workspace_write(api.config["GITLOCK"].repo, branch, recipe)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_new) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -180,9 +184,10 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_delete(recipe_name):
|
||||
"""Delete a recipe from git"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
delete_recipe(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
delete_recipe(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_delete) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -193,6 +198,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_workspace():
|
||||
"""Write a recipe to the workspace"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
if request.headers['Content-Type'] == "text/x-toml":
|
||||
recipe = recipe_from_toml(request.data)
|
||||
@ -200,7 +206,7 @@ def v0_api(api):
|
||||
recipe = recipe_from_dict(request.get_json(cache=False))
|
||||
|
||||
with api.config["GITLOCK"].lock:
|
||||
workspace_write(api.config["GITLOCK"].repo, "master", recipe)
|
||||
workspace_write(api.config["GITLOCK"].repo, branch, recipe)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_workspace) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -211,9 +217,10 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_delete_workspace(recipe_name):
|
||||
"""Delete a recipe from the workspace"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
workspace_delete(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
workspace_delete(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_delete_workspace) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -224,13 +231,14 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_undo(recipe_name, commit):
|
||||
"""Undo changes to a recipe by reverting to a previous commit."""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
revert_recipe(api.config["GITLOCK"].repo, "master", recipe_name, commit)
|
||||
revert_recipe(api.config["GITLOCK"].repo, branch, recipe_name, commit)
|
||||
|
||||
# Read the new recipe and write it to the workspace
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
workspace_write(api.config["GITLOCK"].repo, "master", recipe)
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
workspace_write(api.config["GITLOCK"].repo, branch, recipe)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_undo) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -241,9 +249,10 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_tag(recipe_name):
|
||||
"""Tag a recipe's latest recipe commit as a 'revision'"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
tag_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
tag_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_tag) %s", str(e))
|
||||
return jsonify(status=False, error={"msg":str(e)}), 400
|
||||
@ -254,13 +263,14 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_diff(recipe_name, from_commit, to_commit):
|
||||
"""Return the differences between two commits of a recipe"""
|
||||
branch = request.args.get("branch", "master")
|
||||
try:
|
||||
if from_commit == "NEWEST":
|
||||
with api.config["GITLOCK"].lock:
|
||||
old_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
old_recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
else:
|
||||
with api.config["GITLOCK"].lock:
|
||||
old_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name, from_commit)
|
||||
old_recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name, from_commit)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_diff) %s", str(e))
|
||||
return jsonify(error={"msg":str(e)}), 400
|
||||
@ -268,13 +278,13 @@ def v0_api(api):
|
||||
try:
|
||||
if to_commit == "WORKSPACE":
|
||||
with api.config["GITLOCK"].lock:
|
||||
new_recipe = workspace_read(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
new_recipe = workspace_read(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
elif to_commit == "NEWEST":
|
||||
with api.config["GITLOCK"].lock:
|
||||
new_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
new_recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
else:
|
||||
with api.config["GITLOCK"].lock:
|
||||
new_recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name, to_commit)
|
||||
new_recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name, to_commit)
|
||||
except Exception as e:
|
||||
log.error("(v0_recipes_diff) %s", str(e))
|
||||
return jsonify(error={"msg":str(e)}), 400
|
||||
@ -286,6 +296,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_freeze(recipe_names):
|
||||
"""Return the recipe with the exact modules and packages selected by depsolve"""
|
||||
branch = request.args.get("branch", "master")
|
||||
recipes = []
|
||||
errors = []
|
||||
for recipe_name in [n.strip() for n in sorted(recipe_names.split(","), key=lambda n: n.lower())]:
|
||||
@ -294,7 +305,7 @@ def v0_api(api):
|
||||
recipe = None
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
recipe = workspace_read(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
recipe = workspace_read(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -302,7 +313,7 @@ def v0_api(api):
|
||||
# No workspace version, get the git version (if it exists)
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
errors.append({"recipe":recipe_name, "msg":str(e)})
|
||||
log.error("(v0_recipes_freeze) %s", str(e))
|
||||
@ -346,6 +357,7 @@ def v0_api(api):
|
||||
@crossdomain(origin="*")
|
||||
def v0_recipes_depsolve(recipe_names):
|
||||
"""Return the dependencies for a recipe"""
|
||||
branch = request.args.get("branch", "master")
|
||||
recipes = []
|
||||
errors = []
|
||||
for recipe_name in [n.strip() for n in sorted(recipe_names.split(","), key=lambda n: n.lower())]:
|
||||
@ -354,7 +366,7 @@ def v0_api(api):
|
||||
recipe = None
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
recipe = workspace_read(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
recipe = workspace_read(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@ -362,7 +374,7 @@ def v0_api(api):
|
||||
# No workspace version, get the git version (if it exists)
|
||||
try:
|
||||
with api.config["GITLOCK"].lock:
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, "master", recipe_name)
|
||||
recipe = read_recipe_commit(api.config["GITLOCK"].repo, branch, recipe_name)
|
||||
except Exception as e:
|
||||
errors.append({"recipe":recipe_name, "msg":str(e)})
|
||||
log.error("(v0_recipes_depsolve) %s", str(e))
|
||||
|
@ -27,6 +27,7 @@ class LoraxLintConfig(PocketLintConfig):
|
||||
FalsePositive(r"Module 'pylorax' has no 'version' member"),
|
||||
FalsePositive(r"Instance of 'int' has no .* member"),
|
||||
FalsePositive(r"Catching too general exception Exception"),
|
||||
FalsePositive(r"^E0712.*: Catching an exception which doesn't inherit from (Base|)Exception: GError$"),
|
||||
]
|
||||
|
||||
@property
|
||||
|
@ -460,3 +460,26 @@ class ServerTestCase(unittest.TestCase):
|
||||
self.assertEqual(len(modules), 1)
|
||||
self.assertEqual(modules[0]["name"], "bash")
|
||||
self.assertEqual(modules[0]["dependencies"][0]["name"], "basesystem")
|
||||
|
||||
def test_recipe_new_branch(self):
|
||||
"""Test the /api/v0/recipes/new route with a new branch"""
|
||||
test_recipe = {"description": "An example GlusterFS server with samba",
|
||||
"name":"glusterfs",
|
||||
"version": "0.2.0",
|
||||
"modules":[{"name":"glusterfs", "version":"3.7.*"},
|
||||
{"name":"glusterfs-cli", "version":"3.7.*"}],
|
||||
"packages":[{"name":"samba", "version":"4.2.*"},
|
||||
{"name":"tmux", "version":"2.2"}]}
|
||||
|
||||
resp = self.server.post("/api/v0/recipes/new?branch=test",
|
||||
data=json.dumps(test_recipe),
|
||||
content_type="application/json")
|
||||
data = json.loads(resp.data)
|
||||
self.assertEqual(data, {"status":True})
|
||||
|
||||
resp = self.server.get("/api/v0/recipes/info/glusterfs?branch=test")
|
||||
data = json.loads(resp.data)
|
||||
self.assertNotEqual(data, None)
|
||||
recipes = data.get("recipes")
|
||||
self.assertEqual(len(recipes), 1)
|
||||
self.assertEqual(recipes[0], test_recipe)
|
||||
|
Loading…
Reference in New Issue
Block a user