#72 Add a new endpoint to allow adopting orphaned packages in dist-git
Merged 4 years ago by pingou. Opened 4 years ago by pingou.

@@ -9,9 +9,11 @@ 

  """

  

  from __future__ import unicode_literals, print_function

+ import datetime

  import logging

  

  import flask

+ import requests

  from sqlalchemy.exc import SQLAlchemyError

  

  import pagure.utils
@@ -85,3 +87,126 @@ 

          )

  

      return anitya_get_endpoint(namespace, repo.name)

+ 

+ 

+ def _is_active_in_pdc(name, namespace):

+     """ Queries PDC and return whether the project is active on the master

+     branch in PDC or not.

+     """

+     pdc_url = flask.current_app.config.get("PDC_URL")

+     if not pdc_url:

+         raise pagure.exceptions.APIError(

+             500,

+             error_code=APIERROR.ENOCODE,

+             error="This pagure instance has no PDC_URL configured, please inform"

+             " your pagure administrators"

+         )

+     else:

+         pdc_url = "%s/rest_api/v1/component-branches/" % pdc_url.rstrip("/")

+ 

+     _log.debug("Based PDC url: %s", pdc_url)

+ 

+     to_pdc_namespace = {

+         "rpms": "rpm",

+         "modules": "module",

+         "container": "container",

+     }

+     to_pdc_namespace = flask.current_app.config.get("PDC_NAMESPACES") \

+         or to_pdc_namespace

+ 

+     try:

+         pdc_namespace = to_pdc_namespace[namespace]

+     except:

+         raise pagure.exceptions.APIError(

+             500,

+             error_code=APIERROR.ENOCODE,

+             error="Namespace: %s could not be converted to a PDC namespace" %

+                 namespace

+         )

+ 

+     url = "%s?global_component=%s&name=master&type=%s" % (

+         pdc_url, name, pdc_namespace)

+ 

+     _log.info("Querying PDC at: %s", url)

+     try:

+         req = requests.get(url, timeout=(30, 30))

+     except requests.RequestException as err:

+         raise pagure.exceptions.APIError(

+             500,

+             error_code=APIERROR.ENOCODE,

+             error="An error occured while querying pdc: %s" % err

+         )

+ 

+     try:

+         data = req.json()

+     except:

+         raise pagure.exceptions.APIError(

+             500,

+             error_code=APIERROR.ENOCODE,

+             error="The output of %s could not be converted to JSON" % req.url

+         )

+ 

+     _log.info("%s/%s is active: %s", namespace, name, data["results"][0]["active"])

+     return data["results"][0]["active"] == True

+ 

+ 

+ @DISTGIT_NS.route("/take_orphan/<namespace>/<repo>", methods=["POST"])

+ @api_login_required(acls=["modify_project"])

+ @api_method

+ def take_orphan_endpoint(namespace, repo):

+     """ Updates the current point of contact of orphan packages.

+     """

+     _log.info("Received a request to unorphan: %s/%s", namespace, repo)

+ 

+     repo = _get_repo(repo, namespace=namespace)

+     _check_token(repo, project_token=False)

+ 

+     user_obj = pagure.lib.query.get_user(

+         flask.g.session, flask.g.fas_user.username

+     )

+     if not user_obj:

+         raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOUSER)

+ 

+     if repo.user.user != "orphan":

+         raise pagure.exceptions.APIError(

+             401, error_code=APIERROR.EMODIFYPROJECTNOTALLOWED

+         )

+ 

+     user_grps = set(user_obj.groups)

+     req_grps = set(['packager'])

+     if not user_grps.intersection(req_grps):

+         raise pagure.exceptions.APIError(

+             403,

+             error_code=APIERROR.ENOTHIGHENOUGH,

+             errors="You must be a packager to adopt a package.",

+         )

+ 

+     # Check if the project is retired in PDC

+     if not _is_active_in_pdc(repo.name, repo.namespace):

+         raise pagure.exceptions.APIError(

+             400,

+             error_code=APIERROR.EINVALIDREQ,

+             errors="This project has been retired and cannot be unorphaned "

+                 "here, please open a releng ticket for it.",

+         )

+ 

+     try:

+         repo.user = user_obj

+         flask.g.session.add(repo)

+         flask.g.session.commit()

+     except SQLAlchemyError as err:  # pragma: no cover

+         flask.g.session.rollback()

+         _log.exception(err)

+         raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)

+ 

+     pagure.lib.notify.log(

+         project,

+         topic="project.adopt",

+         msg=dict(

+             project=repo.to_json(public=True), agent=user_obj.username

+         ),

+     )

+ 

+     output = {"point_of_contact": repo.user.user}

+ 

+     return flask.jsonify(output)

Signed-off-by: Pierre-Yves Chibon pingou@pingoured.fr

@till @mohanboddu Could you folks help me determine when we should let someone adopt a package and when not?

Should we always let them adopt and they open a releng ticket to unblock the package if it's blocked?
Should we check the date of update of the project and assume when it was orphaned nobody touched it so we can let the package be unorphaned only during the 2 weeks after it was orphaned?
Should we call PDC to get the status of the package in it?
What do you think is best?

1 new commit added

  • Enforce that the new maintainer be a packager
4 years ago

@pingou If its just about unorphaning, then 2 things to check:

  • Is it retired? Can be checked using dead.package file in dist-git and the branch associated to it or can be also verified using PDC. If its retired, then it needs unretirement, which requires sending a re-review if the package is retired for more than 8 weeks and a whole lot of other stuff.

  • Is the requestor belongs to packager group? We cannot give the packages to anyone who requests to maintain it, it should be only given if the requestor is in packager group.

Is it retired? Can be checked using dead.package file in dist-git and the branch associated to it or can be also verified using PDC. If its retired, then it needs unretirement, which requires sending a re-review if the package is retired for more than 8 weeks and a whole lot of other stuff.

This is a bit more what I need to fix. How do we determine the 8 weeks? And how to determine the retirement? When you adopt a package you adopt all the branches not just one, so I don't think we want to check all of them. Master alone won't work since we have some package that are EPEL only and thus orphaned/retired in master.

Is the requestor belongs to packager group? We cannot give the packages to anyone who requests to maintain it, it should be only given if the requestor is in packager group.

This is already in there (the last commit added :))

Is it retired? Can be checked using dead.package file in dist-git and the branch associated to it or can be also verified using PDC. If its retired, then it needs unretirement, which requires sending a re-review if the package is retired for more than 8 weeks and a whole lot of other stuff.

This is a bit more what I need to fix. How do we determine the 8 weeks? And how to determine the retirement? When you adopt a package you adopt all the branches not just one, so I don't think we want to check all of them. Master alone won't work since we have some package that are EPEL only and thus orphaned/retired in master.

I am not sure how to handle this, I guess you can check the eol values of all the active fedora releases and if they are okay, then unorphan it and if it is retired, then give them a notification that it is retired in certain active fedora releases and ask them to file for unretirement (if they want to maintain it for those releases) and then unorphan it.

Do you know how it is done today? I think we should just replicate the logic here :)

does a retired package always have poc 'orphan' ? Or could it be anyone?

I guess if a package has any active official branches it should be considered just orphaned, if it has none it's retired?

It sure would be nice if we had a better way to mark retired vs orphaned...

Do you know how it is done today? I think we should just replicate the logic here :)

Currently we do the checks manually.

does a retired package always have poc 'orphan' ? Or could it be anyone?

Not always, as a maintainer I can retire a package which will retire the package but will still be owned by me.

I guess if a package has any active official branches it should be considered just orphaned, if it has none it's retired?

Not true, since retirement in only allowed in development branches (rawhide, branched).

It sure would be nice if we had a better way to mark retired vs orphaned...

This is true :smile:

So how about this logic:

  • IF the current POC is "orphan"
  • AND the last time the project was updated in pagure is >= 56 days (8*7)
  • AND "master" is not active in PDC
  • THEN: consider the project retire and inform the user they will have to open a releng ticket to take over the project.
  • OTHERWISE: give the project to the requesting packager.

Question:

Is this correct?

AND the last time the project was updated in pagure is >= 56 days (8*7)
AND "master" is not active in PDC

or do we want?

AND the last time the project was updated in pagure is >= 56 days (8*7)
OR "master" is not active in PDC

So how about this logic:

IF the current POC is "orphan"
AND the last time the project was updated in pagure is >= 56 days (8*7)
AND "master" is not active in PDC
THEN: consider the project retire and inform the user they will have to open a releng ticket to take over the project.
OTHERWISE: give the project to the requesting packager.

If you want to just handle unorphan then

  • If the current POC is orphan
  • AND the requestor is part of packager group (which you already handled)
  • AND "master" is active in PDC
  • THEN assign the package to the requestor, if not, inform the user the package is retired and they will have to open a releng ticket to take over the project.

Although this doesn't handle "active master branch in PDC but inactive for release branches" but that should generally wont happen.

If you want to handle that case as well, let me know, but that brings branch level checking for active releases.

@mohanboddu So we're dropping the 8 weeks check?

If so, I think I have all the changes ready, pushing them for review :)

1 new commit added

  • Check if the project is active in PDC on master
4 years ago

@mohanboddu So we're dropping the 8 weeks check?
If so, I think I have all the changes ready, pushing them for review :)

Yes, its part of unretirement. We can add it in a different way if needed.

  • AND "master" is active in PDC

replace it by

  • AND "master" is active in PDC, if not active, if eol date is <= 56 days from date.today()

But this means you have to change the package eol in pdc to release eol, since it is becoming active again.

  • AND "master" is active in PDC, if not active, if eol date is <= 56 days from date.today()

I am not sure I understand what you mean here.
If master is active=False in PDC, you want to look at the eol date of master?

4 new commits added

  • Send a notification when someone adopts a project
  • Check if the project is active in PDC on master
  • Enforce that the new maintainer be a packager
  • Add a new endpoint to allow adopting orphaned packages in dist-git
4 years ago

Thanks for the review! :)

Pull-Request has been merged by pingou

4 years ago

What exactly is the "8 weeks" supposed to be here?

There are two things to consider:

  • an orphaned package is retired on master after 6+ weeks
  • a retired packager needs a new review if retired for 8+ weeks

8 weeks from the last ownership change doesn't mark any milestone.

@churchyard We are not considering unretirement, this PR is only for unorphaning.

To unorphan, 3 things to check:

  1. The current owner is orphan
  2. The requestor belongs to packager group
  3. Is the rawhide branch is active (PDC Check)

If all satisfied, then unorphan it, if not, for

  1. The package is not orphaned
  2. The requestor dont belong to packager group
  3. The package is retired, file a releng ticket to unretire it.
Metadata