Skip to content

Commit

Permalink
frontend: don't show new action task if namespace is deleting itself
Browse files Browse the repository at this point in the history
wait for the end of the deletion of project to avoid race
condition when other action like fork or create is called
immidiatelly after delete
  • Loading branch information
nikromen committed Aug 7, 2023
1 parent 030dd32 commit d644471
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 8 deletions.
1 change: 1 addition & 0 deletions frontend/coprs_frontend/coprs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2129,6 +2129,7 @@ class Action(db.Model, helpers.Serializer):
# see ActionTypeEnum
action_type = db.Column(db.Integer, nullable=False)
# copr, ...; downcase name of class of modified object
# TODO: replace this in the future with enhanced ActionTypeEnum()
object_type = db.Column(db.String(20))
# id of the modified object
object_id = db.Column(db.Integer)
Expand Down
18 changes: 16 additions & 2 deletions frontend/coprs_frontend/coprs/views/backend_ns/backend_general.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import flask
from copr_common.enums import StatusEnum
from copr_common.enums import StatusEnum, ActionTypeEnum
from coprs import db, app
from coprs import models
from coprs.logic import actions_logic
Expand Down Expand Up @@ -287,14 +287,28 @@ def build_task_canceled(task_id):
@backend_ns.route("/pending-actions/")
def pending_actions():
'get the list of actions backand should take care of'
busy_namespaces = set()
data = []
# waiting repos are ordered
for action in actions_logic.ActionsLogic.get_waiting():
if (
action.object_type == "copr"
and action.action_type == ActionTypeEnum("delete")
):
busy_namespaces.add(action.copr.full_name)
elif action.copr.full_name in busy_namespaces:
# e.g. copr delete _ && copr fork _; will cause race condition
# so don't process new action with the same namespace until delete
# action is processed
# https://github.com/fedora-copr/copr/issues/2698
continue

data.append({
'id': action.id,
'priority': action.priority or action.default_priority,
})
return flask.json.dumps(data)

return flask.json.dumps(data)


@backend_ns.route("/action/<int:action_id>/")
Expand Down
26 changes: 24 additions & 2 deletions frontend/coprs_frontend/tests/coprs_test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -684,13 +684,35 @@ def f_actions(self, f_db):
old_value="asd/qwe",
new_value=None,
result=BackendResultEnum("waiting"),
created_on=int(time.time()))
created_on=int(time.time()),
copr_id=self.c1.id)
self.cancel_build_action = models.Action(action_type=ActionTypeEnum("cancel_build"),
data=json.dumps({'task_id': 123}),
result=BackendResultEnum("waiting"),
created_on=int(time.time()))
created_on=int(time.time()),
copr_id=self.c1.id)
self.db.session.add_all([self.delete_action, self.cancel_build_action])

@pytest.fixture
def f_actions_delete_and_create(self, f_db, f_actions):

Check warning

Code scanning / vcs-diff-lint

CoprsTestCase.f_actions_delete_and_create: Unused argument 'f_db' Warning test

CoprsTestCase.f_actions_delete_and_create: Unused argument 'f_db'

Check warning

Code scanning / vcs-diff-lint

CoprsTestCase.f_actions_delete_and_create: Unused argument 'f_actions' Warning test

CoprsTestCase.f_actions_delete_and_create: Unused argument 'f_actions'
data_dict = {
"ownername": "fooownername",
"projectname": "foocoprname",
"project_dirnames": ["foodirname"],
"chroots": "foochroot",
"appstream": False,
"devel": False,
}

self.create_action = models.Action(action_type=ActionTypeEnum("createrepo"),
object_type="repository",
object_id=0,
data=json.dumps(data_dict),
result=BackendResultEnum("waiting"),
created_on=int(time.time()),
copr_id=self.c1.id)
self.db.session.add(self.create_action)

@pytest.fixture
def f_modules(self):
self.m1 = models.Module(name="first-module", stream="foo", version=1, copr_id=self.c1.id, copr=self.c1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -403,10 +403,7 @@ def test_waiting_actions_only_lists_not_started_or_ended(
def test_pending_actions_list(self, f_users, f_coprs, f_actions, f_db):
r = self.tc.get("/backend/pending-actions/", headers=self.auth_header)
actions = json.loads(r.data.decode("utf-8"))
assert actions == [
{'id': 1, 'priority': DefaultActionPriorityEnum("delete")},
{'id': 2, 'priority': DefaultActionPriorityEnum("cancel_build")}
]
assert actions == [{'id': 1, 'priority': DefaultActionPriorityEnum("delete")}]

self.delete_action.result = BackendResultEnum("success")
self.db.session.add(self.delete_action)
Expand All @@ -415,6 +412,27 @@ def test_pending_actions_list(self, f_users, f_coprs, f_actions, f_db):
r = self.tc.get("/backend/pending-actions/", headers=self.auth_header)
actions = json.loads(r.data.decode("utf-8"))
assert len(actions) == 1
assert actions == [{'id': 2, 'priority': DefaultActionPriorityEnum("cancel_build")}]

def test_dont_propagate_pending_actions_when_deleting(

Check warning

Code scanning / vcs-diff-lint

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Method name "test_dont_propagate_pending_actions_when_deleting" doesn't conform to '[a-z_][a-zA-Z0-9_]{,42}$' pattern Warning test

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Method name "test_dont_propagate_pending_actions_when_deleting" doesn't conform to '[a-z_][a-zA-Z0-9_]{,42}$' pattern
self, f_users, f_coprs, f_actions_delete_and_create, f_db

Check warning

Code scanning / vcs-diff-lint

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_users' Warning test

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_users'

Check warning

Code scanning / vcs-diff-lint

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_coprs' Warning test

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_coprs'

Check warning

Code scanning / vcs-diff-lint

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_actions_delete_and_create' Warning test

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_actions_delete_and_create'

Check warning

Code scanning / vcs-diff-lint

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_db' Warning test

TestWaitingActions.test_dont_propagate_pending_actions_when_deleting: Unused argument 'f_db'
):
r = self.tc.get("/backend/pending-actions/", headers=self.auth_header)
actions = json.loads(r.data.decode("utf-8"))
assert actions == [{'id': 1, 'priority': DefaultActionPriorityEnum("delete")}]

self.delete_action.result = BackendResultEnum("success")
self.db.session.add(self.delete_action)
self.db.session.commit()

# now other pending tasks are unlocked since delete ended
r = self.tc.get("/backend/pending-actions/", headers=self.auth_header)
actions = json.loads(r.data.decode("utf-8"))
assert len(actions) == 2
assert sorted(actions, key=lambda d: d["id"]) == [
{'id': 2, 'priority': DefaultActionPriorityEnum("cancel_build")},
{'id': 3, 'priority': DefaultActionPriorityEnum("createrepo")},
]

def test_get_action_succeeded(self, f_users, f_coprs, f_actions, f_db):
r = self.tc.get("/backend/action/1/",
Expand Down

0 comments on commit d644471

Please sign in to comment.