#233 Extend override by number of days or specific date
Merged 5 years ago by cqi. Opened 5 years ago by cqi.
cqi/fedpkg override-extend  into  master

file modified
+98 -9
@@ -15,12 +15,47 @@ 

  import re

  import platform

  

- from datetime import datetime

+ from datetime import datetime, timedelta

  

  from . import cli  # noqa

  from .lookaside import FedoraLookasideCache

  from pyrpkg.utils import cached_property

  

+ try:

+     from bodhi.client.bindings import BodhiClient as _BodhiClient

+ except ImportError:

+     _BodhiClient = None

+ 

+ 

+ if _BodhiClient is not None:

+     from fedora.client import AuthError

+ 

+     class BodhiClient(_BodhiClient):

+         def save_override(self, *args, **kwargs):

+             try:

+                 super(BodhiClient, self).save_override(*args, **kwargs)

+             except AuthError:

+                 self._session.clear()

+                 self.csrf_token = None

+                 super(BodhiClient, self).save_override(*args, **kwargs)

+ 

+         def extend_override(self, override, expiration_date):

+             data = dict(

+                 nvr=override['nvr'],

+                 notes=override['notes'],

+                 expiration_date=expiration_date,

+                 edited=override['nvr'],

+                 csrf_token=self.csrf(),

+             )

+             try:

+                 return self.send_request(

+                     'overrides/', verb='POST', auth=True, data=data)

+             except AuthError:

+                 self._session.clear()

+                 self.csrf_token = None

+                 return self.send_request(

+                     'overrides/', verb='POST', auth=True, data=data)

+ 

  

  class Commands(pyrpkg.Commands):

  
@@ -238,9 +273,8 @@ 

  

      def create_buildroot_override(self, bodhi_config, build, duration,

                                    notes=''):

-         from bodhi.client.bindings import BodhiClient

- 

-         bodhi = BodhiClient(staging=bodhi_config['staging'])

+         bodhi = BodhiClient(username=self.user,

+                             staging=bodhi_config['staging'])

          result = bodhi.list_overrides(builds=build)

          if result['total'] == 0:

              try:
@@ -254,15 +288,12 @@ 

                  self.log.error(str(e))

                  raise pyrpkg.rpkgError('Cannot create override.')

              else:

-                 self.log.info('Override is created.')

-                 self.log.info('Expiration date: %s',

-                               override['expiration_date'])

-                 self.log.info('Notes: %s', override['notes'])

+                 self.log.info(bodhi.override_str(override, minimal=False))

          else:

              override = result['overrides'][0]

              expiration_date = datetime.strptime(override['expiration_date'],

                                                  '%Y-%m-%d %H:%M:%S')

-             if expiration_date < datetime.now():

+             if expiration_date < datetime.utcnow():

                  self.log.info(

                      'Buildroot override for %s exists and is expired. Consider'

                      ' using command `override extend` to extend duration.',
@@ -271,6 +302,64 @@ 

                  self.log.info('Buildroot override for %s already exists and '

                                'not expired.', build)

  

+     def extend_buildroot_override(self, bodhi_config, build, duration):

+         bodhi = BodhiClient(username=self.user,

+                             staging=bodhi_config['staging'])

+         result = bodhi.list_overrides(builds=build)

+ 

+         if result['total'] == 0:

+             self.log.info('No buildroot override for build %s', build)

+             return

+ 

+         override = result['overrides'][0]

+         expiration_date = datetime.strptime(override['expiration_date'],

+                                             '%Y-%m-%d %H:%M:%S')

+         utcnow = datetime.utcnow()

+ 

+         # bodhi-client binding API save_override calculates expiration

+         # date by adding duration to datetime.utcnow

+         # This comparison should use utcnow as well.

+         if expiration_date < utcnow:

+             self.log.debug('Buildroot override is expired on %s',

+                            override['expiration_date'])

+             self.log.debug('Extend expiration date from today in UTC.')

+             base_date = utcnow

+         else:

+             self.log.debug(

+                 'Extend expiration date from future expiration date.')

+             base_date = expiration_date

+ 

+         if isinstance(duration, datetime):

+             if duration < utcnow:

+                 raise pyrpkg.rpkgError(

+                     'At least, specified expiration date {0} should be '

+                     'future date.'.format(duration.strftime('%Y-%m-%d')))

+             if duration < base_date:

+                 self.log.warning(

+                     'Expiration date %s to be set is before override current'

+                     ' expiration date %s',

+                     duration, base_date)

+             # Keep time unchanged

+             new_expiration_date = datetime(

+                 year=duration.year,

+                 month=duration.month,

+                 day=duration.day,

+                 hour=base_date.hour,

+                 minute=base_date.minute,

+                 second=base_date.second)

+         else:

+             new_expiration_date = base_date + timedelta(days=duration)

+ 

+         try:

+             self.log.debug('Extend override expiration date to %s',

+                            new_expiration_date)

+             override = bodhi.extend_override(override, new_expiration_date)

+         except Exception as e:

+             self.log.error('Cannot extend override expiration.')

+             raise pyrpkg.rpkgError(str(e))

+         else:

+             self.log.info(bodhi.override_str(override, minimal=False))

+ 

  

  if __name__ == "__main__":

      from fedpkg.__main__ import main

file modified
+74 -4
@@ -22,6 +22,8 @@ 

  import six

  import textwrap

  

+ from datetime import datetime

+ 

  from six.moves.configparser import NoSectionError

  from six.moves.configparser import NoOptionError

  from six.moves.urllib_parse import urlparse
@@ -243,6 +245,16 @@ 

              raise argparse.ArgumentTypeError(

                  'override should have 1 day to exist at least.')

  

+         def validate_extend_duration(value):

+             if value.isdigit():

+                 return validate_duration(value)

+             match = re.match(r'(\d{4})-(\d{1,2})-(\d{1,2})', value)

+             if not match:

+                 raise argparse.ArgumentTypeError(

+                     'Invalid expiration date. Valid format: yyyy-mm-dd.')

+             y, m, d = match.groups()

+             return datetime(year=int(y), month=int(m), day=int(d))

+ 

          override_parser = self.subparsers.add_parser(

              'override',

              help='Manage buildroot overrides')
@@ -262,13 +274,13 @@ 

  Create a buildroot override from build guessed from release branch. Note that,

  command must run inside a package repository.

  

-     fedpkg switch-branch f28

-     fedpkg override create --duration 5

+     {0} switch-branch f28

+     {0} override create --duration 5

  

  Create for a specified build:

  

-     fedpkg override create --duration 5 package-1.0-1.fc28

- ''')

+     {0} override create --duration 5 package-1.0-1.fc28

+ '''.format(self.name))

          create_parser.add_argument(

              '--duration',

              type=validate_duration,
@@ -286,6 +298,48 @@ 

                   ' guessed from current release branch.')

          create_parser.set_defaults(command=self.create_buildroot_override)

  

+         extend_parser = override_subparser.add_parser(

+             'extend',

+             help='Extend buildroot override expiration',

+             formatter_class=argparse.RawDescriptionHelpFormatter,

+             description='''\

+ Extend buildroot override expiration.

+ 

+ An override expiration date could be extended by number of days or a specific

+ date. If override is expired, expiration date will be extended from the date

+ of today, otherwise from the expiration date.

+ 

+ Command extend accepts an optional build NVR to find out its override in

+ advance. If there is no such an override created previously, please use

+ `override create` to create one. If build NVR is omitted, command extend must

+ run inside a package repository and build will be guessed from current release

+ branch.

+ 

+ Examples:

+ 

+ 1. To give 2 days to override for build somepkg-0.2-1.fc28

+ 

+     {0} override extend 2 somepkg-0.2-1.fc28

+ 

+ 2. To extend expiration date to 2018-7-1

+ 

+     cd /path/to/somepkg

+     {0} switch-branch f28

+     {0} override extend 2018-7-1

+ '''.format(self.name))

+         extend_parser.add_argument(

+             'duration',

+             type=validate_extend_duration,

+             help='Number of days to extend the expiration date, or set the '

+                  'expiration date directly. Valid date format: yyyy-mm-dd.')

+         extend_parser.add_argument(

+             'NVR',

+             nargs='?',

+             help='Buildroot override expiration for this build will be '

+                  'extended. If omitted, build will be guessed from current '

+                  'release branch.')

+         extend_parser.set_defaults(command=self.extend_buildroot_override)

+ 

      # Target functions go here

      def retire(self):

          # Skip if package is already retired...
@@ -692,9 +746,25 @@ 

      def create_buildroot_override(self):

          """Create a buildroot override in Bodhi"""

          check_bodhi_version()

+         if self.args.NVR:

+             if not self.cmd.anon_kojisession.getBuild(self.args.NVR):

+                 raise rpkgError(

+                     'Build {0} does not exist.'.format(self.args.NVR))

          bodhi_config = self._get_bodhi_config()

          self.cmd.create_buildroot_override(

              bodhi_config,

              build=self.args.NVR or self.cmd.nvr,

              duration=self.args.duration,

              notes=self.args.notes)

+ 

+     def extend_buildroot_override(self):

+         check_bodhi_version()

+         if self.args.NVR:

+             if not self.cmd.anon_kojisession.getBuild(self.args.NVR):

+                 raise rpkgError(

+                     'Build {0} does not exist.'.format(self.args.NVR))

+         bodhi_config = self._get_bodhi_config()

+         self.cmd.extend_buildroot_override(

+             bodhi_config,

+             build=self.args.NVR or self.cmd.nvr,

+             duration=self.args.duration)

file modified
+294 -18
@@ -29,6 +29,7 @@ 

  from datetime import datetime, timedelta

  from tempfile import mkdtemp

  from os import rmdir

+ from freezegun import freeze_time

  

  import six

  from six.moves.configparser import NoOptionError
@@ -1137,9 +1138,27 @@ 

  class TestBodhiOverride(CliTestCase):

      """Test command override"""

  

-     @patch('fedpkg.cli.check_bodhi_version')

-     @patch('bodhi.client.bindings.BodhiClient')

-     def test_create_for_given_build(self, BodhiClient, check_bodhi_version):

+     def setUp(self):

+         super(TestBodhiOverride, self).setUp()

+ 

+         self.cbv_p = patch('fedpkg.cli.check_bodhi_version')

+         self.cbv_m = self.cbv_p.start()

+ 

+         self.anon_kojisession_p = patch('fedpkg.Commands.anon_kojisession',

+                                         new_callable=PropertyMock)

+         self.anon_kojisession_m = self.anon_kojisession_p.start()

+         self.kojisession = self.anon_kojisession_m.return_value

+ 

+         # Fake build returned from Koji for the specified build NVR in tests

+         self.kojisession.getBuild.return_value = {'build_id': 1}

+ 

+     def tearDown(self):

+         self.anon_kojisession_p.stop()

+         self.cbv_p.stop()

+         super(TestBodhiOverride, self).tearDown()

+ 

+     @patch('fedpkg.BodhiClient')

+     def test_create_for_given_build(self, BodhiClient):

          bodhi_client = BodhiClient.return_value

          bodhi_client.list_overrides.return_value = {'total': 0}

          expiration_date = datetime.now() + timedelta(days=7)
@@ -1161,20 +1180,20 @@ 

              with patch.object(cli.cmd, 'log') as log:

                  cli.create_buildroot_override()

  

-                 log.info.assert_any_call('Expiration date: %s',

-                                          new_override['expiration_date'])

-                 log.info.assert_any_call('Notes: %s', new_override['notes'])

+                 bodhi_client.override_str.assert_called_once_with(

+                     bodhi_client.save_override.return_value,

+                     minimal=False)

+                 log.info.assert_any_call(

+                     bodhi_client.override_str.return_value)

  

          bodhi_client.save_override.assert_called_once_with(

              nvr='rpkg-1.54-1.fc28',

              duration=7,

              notes='build for fedpkg')

  

-     @patch('fedpkg.cli.check_bodhi_version')

-     @patch('bodhi.client.bindings.BodhiClient')

+     @patch('fedpkg.BodhiClient')

      @patch('fedpkg.Commands.nvr', new_callable=PropertyMock)

-     def test_create_from_current_branch(

-             self, nvr, BodhiClient, check_bodhi_version):

+     def test_create_from_current_branch(self, nvr, BodhiClient):

          nvr.return_value = 'rpkg-1.54-2.fc28'

          bodhi_client = BodhiClient.return_value

          bodhi_client.list_overrides.return_value = {'total': 0}
@@ -1194,11 +1213,9 @@ 

              duration=7,

              notes='build for fedpkg')

  

-     @patch('fedpkg.cli.check_bodhi_version')

-     @patch('bodhi.client.bindings.BodhiClient')

+     @patch('fedpkg.BodhiClient')

      @patch('fedpkg.Commands.nvr', new_callable=PropertyMock)

-     def test_override_already_exists_but_expired(

-             self, nvr, BodhiClient, check_bodhi_version):

+     def test_override_already_exists_but_expired(self, nvr, BodhiClient):

          nvr.return_value = 'rpkg-1.54-2.fc28'

          today = datetime.today()

          fake_expiration_date = today - timedelta(days=10)
@@ -1225,11 +1242,9 @@ 

                      ' using command `override extend` to extend duration.',

                      'rpkg-1.54-2.fc28')

  

-     @patch('fedpkg.cli.check_bodhi_version')

-     @patch('bodhi.client.bindings.BodhiClient')

+     @patch('fedpkg.BodhiClient')

      @patch('fedpkg.Commands.nvr', new_callable=PropertyMock)

-     def test_override_already_exists_but_not_expired(

-             self, nvr, BodhiClient, check_bodhi_version):

+     def test_override_already_exists_but_not_expired(self, nvr, BodhiClient):

          nvr.return_value = 'rpkg-1.54-2.fc28'

          today = datetime.today()

          fake_expiration_date = today + timedelta(days=10)
@@ -1254,3 +1269,264 @@ 

                  log.info.assert_any_call(

                      'Buildroot override for %s already exists and not '

                      'expired.', 'rpkg-1.54-2.fc28')

+ 

+ 

+ @unittest.skipUnless(bodhi, 'Skip if no supported bodhi-client is available')

+ class TestBodhiOverrideExtend(CliTestCase):

+     """Test command `override extend`"""

+ 

+     def setUp(self):

+         super(TestBodhiOverrideExtend, self).setUp()

+ 

+         # No need to check bodhi version for tests

+         self.cbv_p = patch('fedpkg.cli.check_bodhi_version')

+         self.cbv_p.start()

+ 

+         self.anon_kojisession_p = patch('fedpkg.Commands.anon_kojisession',

+                                         new_callable=PropertyMock)

+         self.anon_kojisession_m = self.anon_kojisession_p.start()

+         self.kojisession = self.anon_kojisession_m.return_value

+ 

+         # Fake build returned from Koji for the specified build NVR in tests

+         self.kojisession.getBuild.return_value = {'build_id': 1}

+ 

+     def tearDown(self):

+         self.anon_kojisession_p.stop()

+         self.cbv_p.stop()

+         super(TestBodhiOverrideExtend, self).tearDown()

+ 

+     def test_specified_build_not_exist(self):

+         self.kojisession.getBuild.return_value = None

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', '7', 'somepkg-1.54-2.fc28'

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             six.assertRaisesRegex(

+                 self, rpkgError, 'Build somepkg-1.54-2.fc28 does not exist.',

+                 cli.extend_buildroot_override)

+ 

+     @patch('fedpkg.BodhiClient.list_overrides')

+     def test_no_override_for_build(self, list_overrides):

+         list_overrides.return_value = {'total': 0}

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', '7', 'somepkg-1.54-2.fc28'

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             with patch.object(cli.cmd, 'log') as log:

+                 cli.extend_buildroot_override()

+                 log.info.assert_any_call('No buildroot override for build %s',

+                                          'somepkg-1.54-2.fc28')

+ 

+     @patch('fedpkg.BodhiClient.list_overrides')

+     @patch('fedpkg.BodhiClient.csrf')

+     @patch('fedpkg.BodhiClient.send_request')

+     def test_extend_override_by_days(

+             self, send_request, csrf, list_overrides):

+         utcnow = datetime.utcnow()

+         override_expiration_date = utcnow + timedelta(days=7)

+         build_nvr = 'somepkg-1.54-2.fc28'

+         build_override = {

+             'expiration_date':

+                 override_expiration_date.strftime('%Y-%m-%d %H:%M:%S'),

+             'nvr': build_nvr,

+             'notes': 'build for other package',

+             'build': {'nvr': build_nvr},

+             'submitter': {'name': 'someone'},

+             'expired_date': utcnow - timedelta(days=20)

+         }

+ 

+         list_overrides.return_value = {

+             'total': 1,

+             'overrides': [build_override]

+         }

+         edited_override = build_override.copy()

+         expected_expiration_date = override_expiration_date + timedelta(days=2)

+         edited_override['expiration_date'] = \

+             expected_expiration_date.strftime('%Y-%m-%d %H:%M:%S')

+         send_request.return_value = edited_override

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', '2', build_nvr

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             cli.extend_buildroot_override()

+ 

+         # Ensure no microsecond is included in the expected expiration data

+         new_date = override_expiration_date + timedelta(days=2)

+         expected_expiration_date = datetime(year=new_date.year,

+                                             month=new_date.month,

+                                             day=new_date.day,

+                                             hour=new_date.hour,

+                                             minute=new_date.minute,

+                                             second=new_date.second)

+         request_data = {

+             'expiration_date': expected_expiration_date,

+             'nvr': build_nvr,

+             'notes': build_override['notes'],

+             'edited': build_nvr,

+             'csrf_token': csrf.return_value,

+         }

+         send_request.assert_called_once_with(

+             'overrides/', verb='POST', auth=True, data=request_data)

+ 

+     @patch('fedpkg.BodhiClient.list_overrides')

+     @patch('fedpkg.BodhiClient.csrf')

+     @patch('fedpkg.BodhiClient.send_request')

+     def test_extend_override_by_specific_date(

+             self, send_request, csrf, list_overrides):

+         utcnow = datetime.utcnow()

+         override_expiration_date = utcnow + timedelta(days=7)

+         build_nvr = 'somepkg-1.54-2.fc28'

+         build_override = {

+             'expiration_date':

+                 override_expiration_date.strftime('%Y-%m-%d %H:%M:%S'),

+             'nvr': build_nvr,

+             'notes': 'build for other package',

+             'build': {'nvr': build_nvr},

+             'submitter': {'name': 'someone'},

+             'expired_date': utcnow - timedelta(days=20)

+         }

+ 

+         list_overrides.return_value = {

+             'total': 1,

+             'overrides': [build_override]

+         }

+ 

+         new_expiration_date = override_expiration_date + timedelta(days=4)

+         # Ensure no microsecond is included in the expected expiration data

+         expected_expiration_date = datetime(

+             year=new_expiration_date.year,

+             month=new_expiration_date.month,

+             day=new_expiration_date.day,

+             hour=override_expiration_date.hour,

+             minute=override_expiration_date.minute,

+             second=override_expiration_date.second)

+ 

+         edited_override = build_override.copy()

+         edited_override['expiration_date'] = \

+             expected_expiration_date.strftime('%Y-%m-%d %H:%M:%S')

+         send_request.return_value = edited_override

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', new_expiration_date.strftime('%Y-%m-%d'),

+             build_nvr

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             cli.extend_buildroot_override()

+ 

+         request_data = {

+             'expiration_date': expected_expiration_date,

+             'nvr': build_nvr,

+             'notes': build_override['notes'],

+             'edited': build_nvr,

+             'csrf_token': csrf.return_value,

+         }

+         send_request.assert_called_once_with(

+             'overrides/', verb='POST', auth=True, data=request_data)

+ 

+     @patch('fedpkg.BodhiClient.list_overrides')

+     @patch('fedpkg.BodhiClient.csrf')

+     @patch('fedpkg.BodhiClient.send_request')

+     @freeze_time('2018-06-08 16:17:30')

+     def test_extend_for_expired_override(

+             self, send_request, csrf, list_overrides):

+         utcnow = datetime.utcnow()

+         # Make override expired

+         override_expiration_date = utcnow - timedelta(days=7)

+         build_nvr = 'somepkg-1.54-2.fc28'

+         build_override = {

+             'expiration_date':

+                 override_expiration_date.strftime('%Y-%m-%d %H:%M:%S'),

+             'nvr': build_nvr,

+             'notes': 'build for other package',

+             'build': {'nvr': build_nvr},

+             'submitter': {'name': 'someone'},

+             'expired_date': utcnow - timedelta(days=20)

+         }

+ 

+         list_overrides.return_value = {

+             'total': 1,

+             'overrides': [build_override]

+         }

+ 

+         # Ensure no microsecond is included in the expected expiration data

+         new_date = utcnow + timedelta(days=2)

+         expected_expiration_date = datetime(

+             year=new_date.year,

+             month=new_date.month,

+             day=new_date.day,

+             hour=new_date.hour,

+             minute=new_date.minute,

+             second=new_date.second)

+ 

+         edited_override = build_override.copy()

+         edited_override['expiration_date'] = \

+             expected_expiration_date.strftime('%Y-%m-%d %H:%M:%S')

+         send_request.return_value = edited_override

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', '2', build_nvr

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             cli.extend_buildroot_override()

+ 

+         request_data = {

+             'expiration_date': expected_expiration_date,

+             'nvr': build_nvr,

+             'notes': build_override['notes'],

+             'edited': build_nvr,

+             'csrf_token': csrf.return_value,

+         }

+         send_request.assert_called_once_with(

+             'overrides/', verb='POST', auth=True, data=request_data)

+ 

+     @patch('fedpkg.BodhiClient.list_overrides')

+     @patch('fedpkg.BodhiClient.csrf')

+     @patch('fedpkg.BodhiClient.extend_override')

+     def test_error_handled_properly_when_fail_to_request(

+             self, extend_override, csrf, list_overrides):

+         extend_override.side_effect = Exception

+ 

+         utcnow = datetime.utcnow()

+         override_expiration_date = utcnow + timedelta(days=7)

+         build_nvr = 'somepkg-1.54-2.fc28'

+ 

+         list_overrides.return_value = {

+             'total': 1,

+             'overrides': [{

+                 'expiration_date':

+                     override_expiration_date.strftime('%Y-%m-%d %H:%M:%S'),

+                 'nvr': build_nvr,

+                 'notes': 'build for other package',

+                 'build': {'nvr': build_nvr},

+                 'submitter': {'name': 'someone'},

+                 'expired_date': utcnow - timedelta(days=20)

+             }]

+         }

+ 

+         cli_cmd = [

+             'fedpkg', '--path', self.cloned_repo_path,

+             'override', 'extend', '2', build_nvr

+         ]

+ 

+         with patch('sys.argv', new=cli_cmd):

+             cli = self.new_cli()

+             six.assertRaisesRegex(self, rpkgError, '',

+                                   cli.extend_buildroot_override)

file modified
+1
@@ -1,3 +1,4 @@ 

  mock == 1.0.1

  nose == 1.3.7

  nose-cov

+ freezegun

This patch adds a new subcommand extend to command override, which is
able to extend an override expiration date.

Fixes #67

Signed-off-by: Chenxiong Qi cqi@redhat.com

rebased onto 4434b1f

5 years ago

Pretty please pagure-ci rebuild

This code should be added to Bodhi directly. As a temporary workaround until Bodhi has this functionality it might be fine, but it still feels a bit hacky.

1 new commit added

  • Refine command override create
5 years ago

Pretty please pagure-ci rebuild

2 new commits added

  • Refine command override create
  • Extend override by number of days or specific date
5 years ago

Pretty please pagure-ci rebuild

1 new commit added

  • Handle Bodhi login automatically
5 years ago

This code should be added to Bodhi directly. As a temporary workaround until Bodhi has this functionality it might be fine, but it still feels a bit hacky.

@lsedlar I think you mean the custom BodhiClient. It would be good to have the extend_override in Bodhi Python binding. Not sure if it is required by bodhi. Anyways, I'll try to propose a patch to Bodhi.

@lsedlar Just add a new commit. I tested the new command, so far it works well for me. Please review again. Thanks.

3 new commits added

  • Handle Bodhi login automatically
  • Refine command override create
  • Extend override by number of days or specific date
5 years ago

Pretty please pagure-ci rebuild

Ping for another round of review.

Commit 0146d16 fixes this pull-request

Pull-Request has been merged by cqi

5 years ago

Pull-Request has been merged by cqi

5 years ago