#2991 CLI channels, hosts methods works with older hub
Merged 9 months ago by tkopecek. Opened 9 months ago by jcupova.
jcupova/koji issue-2990  into  master

file modified
+48 -16
@@ -312,7 +312,19 @@ 

      if len(args) != 1:

          parser.error(_("Please specify one channel name"))

      activate_session(session, goptions)

-     channel_id = session.addChannel(args[0], description=options.description)

+     channel_name = args[0]

+     try:

+         channel_id = session.addChannel(channel_name, description=options.description)

+     except koji.GenericError as ex:

+         msg = str(ex)

+         if 'channel %s already exists' % channel_name in msg:

+             error("channel %s already exists" % channel_name)

+         elif 'Invalid method:' in msg:

+             version = session.getKojiVersion()

+             error("addChannel is available on hub from Koji 1.26 version, your version is %s" %

+                   version)

+         else:

+             error(msg)

      print("%s added: id %d" % (args[0], channel_id))

  

  
@@ -365,7 +377,16 @@ 

      cinfo = session.getChannel(args[0])

      if not cinfo:

          error("No such channel: %s" % args[0])

-     result = session.editChannel(args[0], **vals)

+     try:

+         result = session.editChannel(args[0], **vals)

+     except koji.GenericError as ex:

+         msg = str(ex)

+         if 'Invalid method:' in msg:

+             version = session.getKojiVersion()

+             error("editChannel is available on hub from Koji 1.26 version, your version is %s" %

+                   version)

+         else:

+             print(msg)

      if not result:

          error(_("No changes made, please correct the command line"))

  
@@ -2988,8 +3009,11 @@ 

      opts = {}

      if options.enabled is not None:

          opts['enabled'] = options.enabled

-     channels = sorted([x for x in session.listChannels(**opts)], key=lambda x: x['name'])

- 

+     try:

+         channels = sorted([x for x in session.listChannels(**opts)], key=lambda x: x['name'])

+     except koji.ParameterError:

+         channels = sorted([x for x in session.listChannels()], key=lambda x: x['name'])

+     first_item = channels[0]

      session.multicall = True

      for channel in channels:

          session.listHosts(channelID=channel['id'])
@@ -2999,14 +3023,17 @@ 

          channel['ready'] = len([x for x in hosts if x['ready']])

          channel['capacity'] = sum([x['capacity'] for x in hosts])

          channel['load'] = sum([x['task_load'] for x in hosts])

-         channel['comment'] = truncate_string(channel['comment'])

-         channel['description'] = truncate_string(channel['description'])

+         if 'comment' in first_item:

+             channel['comment'] = truncate_string(channel['comment'])

+         if 'description' in first_item:

+             channel['description'] = truncate_string(channel['description'])

          if channel['capacity']:

              channel['perc_load'] = channel['load'] / channel['capacity'] * 100.0

          else:

              channel['perc_load'] = 0.0

-         if not channel['enabled']:

-             channel['name'] = channel['name'] + ' [disabled]'

+         if 'enabled' in first_item:

+             if not channel['enabled']:

+                 channel['name'] = channel['name'] + ' [disabled]'

      if channels:

          longest_channel = max([len(ch['name']) for ch in channels])

      else:
@@ -3021,16 +3048,16 @@ 

              hdr = '{channame:<{longest_channel}}Enabled  Ready Disbld   Load    Cap   ' \

                    'Perc    '

              hdr = hdr.format(longest_channel=longest_channel, channame='Channel')

-             if options.description:

+             if options.description and 'description' in first_item:

                  hdr += "Description".ljust(53)

-             if options.comment:

+             if options.comment and 'comment' in first_item:

                  hdr += "Comment".ljust(53)

              print(hdr)

          mask = "%%(name)-%ss %%(enabled_host)6d %%(ready)6d %%(disabled)6d %%(load)6d %%(" \

                 "capacity)6d %%(perc_load)6d%%%%" % longest_channel

-         if options.description:

+         if options.description and 'description' in first_item:

              mask += "   %(description)-50s"

-         if options.comment:

+         if options.comment and 'comment' in first_item:

              mask += "   %(comment)-50s"

          for channel in channels:

              print(mask % channel)
@@ -3110,19 +3137,24 @@ 

      if options.show_channels:

          with session.multicall() as m:

              result = [m.listChannels(host['id']) for host in hosts]

+         first_line_channel = result[0].result

          for host, channels in zip(hosts, result):

              list_channels = []

              for c in channels.result:

-                 if c['enabled']:

-                     list_channels.append(c['name'])

+                 if 'enabled' in first_line_channel:

+                     if c['enabled']:

+                         list_channels.append(c['name'])

+                     else:

+                         list_channels.append('*' + c['name'])

                  else:

-                     list_channels.append('*' + c['name'])

+                     list_channels.append(c['name'])

              host['channels'] = ','.join(sorted(list_channels))

  

      if hosts:

          longest_host = max([len(h['name']) for h in hosts])

      else:

          longest_host = 8

+ 

      if not options.quiet:

          hdr = "{hostname:<{longest_host}} Enb Rdy Load/Cap  Arches           " \

                "Last Update                         "
@@ -7974,7 +8006,7 @@ 

          version = session.getKojiVersion()

          print("Hub:    %s" % version)

      except koji.GenericError:

-         print("Hub:    Can' determine (older than 1.23)")

+         print("Hub:    Can't determine (older than 1.23)")

  

  

  def anon_handle_userinfo(goptions, session, args):

@@ -37,13 +37,35 @@ 

      @mock.patch('sys.stderr', new_callable=six.StringIO)

      @mock.patch('koji_cli.commands.activate_session')

      def test_handle_add_channel_exist(self, activate_session_mock, stderr):

-         expected = 'channel %(name)s already exists (id=%(id)i)'

+         expected_api = 'channel %s already exists (id=%s)' % (self.channel_name, self.channel_id)

+         expected = 'channel %s already exists\n' % self.channel_name

  

-         self.session.addChannel.side_effect = koji.GenericError(expected)

-         with self.assertRaises(koji.GenericError) as ex:

+         self.session.addChannel.side_effect = koji.GenericError(expected_api)

+         with self.assertRaises(SystemExit) as ex:

              handle_add_channel(self.options, self.session,

                                 ['--description', self.description, self.channel_name])

-         self.assertEqual(str(ex.exception), expected)

+         self.assertExitCode(ex, 1)

+         actual = stderr.getvalue()

+         self.assertMultiLineEqual(actual, expected)

+         activate_session_mock.assert_called_once_with(self.session, self.options)

+         self.session.addChannel.assert_called_once_with(self.channel_name,

+                                                         description=self.description)

+ 

+     @mock.patch('sys.stderr', new_callable=six.StringIO)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_handle_add_channel_older_hub(self, activate_session_mock, stderr):

+         expected_api = 'Invalid method: addChannel'

+         expected = 'addChannel is available on hub from Koji 1.26 version, your version ' \

+                    'is 1.25.1\n'

+         self.session.getKojiVersion.return_value = '1.25.1'

+ 

+         self.session.addChannel.side_effect = koji.GenericError(expected_api)

+         with self.assertRaises(SystemExit) as ex:

+             handle_add_channel(self.options, self.session,

+                                ['--description', self.description, self.channel_name])

+         self.assertExitCode(ex, 1)

+         actual = stderr.getvalue()

+         self.assertMultiLineEqual(actual, expected)

          activate_session_mock.assert_called_once_with(self.session, self.options)

          self.session.addChannel.assert_called_once_with(self.channel_name,

                                                          description=self.description)
@@ -79,7 +101,7 @@ 

          self.assertMultiLineEqual(actual, expected_stderr)

          activate_session_mock.assert_not_called()

  

-     def test_handle_add_host_help(self):

+     def test_handle_add_channel_help(self):

          self.assert_help(

              handle_add_channel,

              """Usage: %s add-channel [options] <channel_name>

@@ -6,6 +6,7 @@ 

  import mock

  import six

  

+ import koji

  from koji_cli.commands import handle_edit_channel

  from . import utils

  
@@ -61,6 +62,26 @@ 

          self.session.editChannel.assert_called_once_with(self.channel_old, name=self.channel_new,

                                                           description=self.description)

  

+     @mock.patch('sys.stderr', new_callable=six.StringIO)

+     @mock.patch('koji_cli.commands.activate_session')

+     def test_handle_edit_channel_older_hub(self, activate_session_mock, stderr):

+         expected_api = 'Invalid method: editChannel'

+         expected = 'editChannel is available on hub from Koji 1.26 version, your version ' \

+                    'is 1.25.1\n'

+         self.session.getKojiVersion.return_value = '1.25.1'

+ 

+         self.session.editChannel.side_effect = koji.GenericError(expected_api)

+         with self.assertRaises(SystemExit) as ex:

+             handle_edit_channel(self.options, self.session,

+                                 [self.channel_old, '--name', self.channel_new,

+                                  '--description', self.description])

+         self.assertExitCode(ex, 1)

+         actual = stderr.getvalue()

+         self.assertMultiLineEqual(actual, expected)

+         activate_session_mock.assert_called_once_with(self.session, self.options)

+         self.session.editChannel.assert_called_once_with(self.channel_old, name=self.channel_new,

+                                                          description=self.description)

+ 

  

  if __name__ == '__main__':

      unittest.main()

It is the same for description when testing:

2021-08-23 15:45:58,612 [ERROR] koji: KeyError: 'description'

rebased onto c53dabbea969fd3e2c3b4b4583bf13924c6819ac

9 months ago

@tkopecek description fixed and also I found the same problem with enabled, also fixed.

rebased onto 92a7279e5d216a35bae1758bae9505e7cfebf5fd

9 months ago

Would you please update the commit title and PR title? This change fixes more than list-channels now

rebased onto 7515dd05d7afbb8c4f9380373db84d741e5d8d5f

9 months ago

Let's narrow this further, like so:

    except koji.GenericError as e:
        if 'Invalid method' in str(e):

rebased onto a836503201d0c70d314d4d4cbc5e8f58b8a9851b

9 months ago

rebased onto 3775744b7c8709814ee7d04cf6f1b8837e2e6dbe

9 months ago

Metadata Update from @tkopecek:
- Pull-request tagged with: testing-ready

9 months ago

list-hosts --show-channels is also affected

rebased onto 957f128

9 months ago

Commit 1dd05be fixes this pull-request

Pull-Request has been merged by tkopecek

9 months ago

Metadata Update from @mfilip:
- Pull-request tagged with: testing-done

8 months ago