#891 Web UI python3 changes
Merged 7 months ago by mikem. Opened a year ago by tkopecek.
tkopecek/koji issue890  into  master

file modified
+73 -11

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

  %bcond_with python3

  %endif

  

+ # don't build py2 packages for py3-only systems

+ %if 0%{with python3} && (0%{?fedora} > 32 || 0%{?rhel} > 7)

+     %define with_python2 0

+ %else

+     %define with_python2 1

+ %endif

+ 

  # Compatibility with RHEL. These macros have been added to EPEL but

  # not yet to RHEL proper.

  # https://bugzilla.redhat.com/show_bug.cgi?id=1307190

@@ -58,6 +65,7 @@ 

  Koji is a system for building and tracking RPMS.  The base package

  contains shared libraries and the command-line interface.

  

+ %if 0%{with_python2}

  %package -n python2-%{name}

  Summary: Build system tools python library

  %{?python_provide:%python_provide python2-%{name}}

@@ -79,6 +87,7 @@ 

  

  %description -n python2-%{name}

  desc

+ %endif

  

  %if 0%{with python3}

  %package -n python%{python3_pkgversion}-%{name}

@@ -100,6 +109,7 @@ 

  desc

  %endif

  

+ %if 0%{with_python2}

  %package -n python2-%{name}-cli-plugins

  Summary: Koji client plugins

  Group: Applications/Internet

@@ -108,6 +118,7 @@ 

  

  %description -n python2-%{name}-cli-plugins

  Plugins to the koji command-line interface

+ %endif

  

  %if 0%{with python3}

  %package -n python%{python3_pkgversion}-%{name}-cli-plugins

@@ -240,10 +251,12 @@ 

  %description utils

  Utilities for the Koji system

  

- %package web

+ %if 0%{with_python2}

+ %package -n python2-%{name}-web

  Summary: Koji Web UI

  Group: Applications/Internet

  License: LGPLv2

+ %{?python_provide:%python_provide python2-%{name}-web}

  Requires: httpd

  Requires: mod_wsgi

  %if 0%{?fedora} >= 21 || 0%{?rhel} >= 7

@@ -254,12 +267,32 @@ 

  %endif

  Requires: python-psycopg2

  Requires: python-cheetah

- Requires: %{name} = %{version}-%{release}

- # we need the python2 lib here

  Requires: python2-%{name} = %{version}-%{release}

+ Provides: koji-web = %{version}-%{release}

+ Obsoletes: koji-web < 1.16.2

  

- %description web

+ %description -n python2-%{name}-web

  koji-web is a web UI to the Koji system.

+ %endif

+ 

+ %if 0%{with python3}

+ %package -n python%{python3_pkgversion}-%{name}-web

+ Summary: Koji Web UI

+ Group: Applications/Internet

+ License: LGPLv2

+ %{?python_provide:%python_provide python%{python3_pkgversion}-%{name}-web}

+ Requires: httpd

+ Requires: python%{python3_pkgversion}-mod_wsgi

+ Requires: mod_auth_gssapi

+ Requires: python%{python3_pkgversion}-psycopg2

+ Requires: python%{python3_pkgversion}-cheetah

+ Requires: python%{python3_pkgversion}-%{name} = %{version}-%{release}

+ Provides: koji-web = %{version}-%{release}

+ Obsoletes: koji-web < 1.16.2

+ 

+ %description -n python%{python3_pkgversion}-%{name}-web

+ koji-web is a web UI to the Koji system.

+ %endif

  

  %prep

  %setup -q

@@ -268,14 +301,15 @@ 

  

  %install

  rm -rf $RPM_BUILD_ROOT

+ %if 0%{with_python2}

  make DESTDIR=$RPM_BUILD_ROOT PYTHON=%{__python2} %{?install_opt} install

+ %endif

  %if 0%{with python3}

- cd koji

- make DESTDIR=$RPM_BUILD_ROOT PYTHON=%{__python3} %{?install_opt} install

- cd ../cli

- make DESTDIR=$RPM_BUILD_ROOT PYTHON=%{__python3} %{?install_opt} install

- cd ../plugins

- make DESTDIR=$RPM_BUILD_ROOT PYTHON=%{__python3} %{?install_opt} install

+ for d in koji cli plugins www ; do

+     pushd $d

+     make DESTDIR=$RPM_BUILD_ROOT PYTHON=%{__python3} %{?install_opt} install

+     popd

+ done

  # alter python interpreter in koji CLI

  sed -i 's/\#\!\/usr\/bin\/python2/\#\!\/usr\/bin\/python3/' $RPM_BUILD_ROOT/usr/bin/koji

  %endif

@@ -290,10 +324,12 @@ 

  %dir /etc/koji.conf.d

  %doc docs Authors COPYING LGPL

  

+ %if 0%{with_python2}

  %files -n python2-%{name}

  %defattr(-,root,root)

  %{python2_sitelib}/%{name}

  %{python2_sitelib}/koji_cli

+ %endif

  

  %if 0%{with python3}

  %files -n python%{python3_pkgversion}-koji

@@ -301,12 +337,14 @@ 

  %{python3_sitelib}/koji_cli

  %endif

  

+ %if 0%{with_python2}

  %files -n python2-%{name}-cli-plugins

  %defattr(-,root,root)

  %{python2_sitelib}/koji_cli_plugins

  # we don't have config files for default plugins yet

  #%%dir %%{_sysconfdir}/koji/plugins

  #%%config(noreplace) %%{_sysconfdir}/koji/plugins/*.conf

+ %endif

  

  %if 0%{with python3}

  %files -n python%{python3_pkgversion}-%{name}-cli-plugins

@@ -317,6 +355,7 @@ 

  #%%config(noreplace) %%{_sysconfdir}/koji/plugins/*.conf

  %endif

  

+ %if 0%{with_python2}

  %files hub

  %defattr(-,root,root)

  %{_datadir}/koji-hub

@@ -325,21 +364,27 @@ 

  %dir /etc/koji-hub

  %config(noreplace) /etc/koji-hub/hub.conf

  %dir /etc/koji-hub/hub.conf.d

+ %endif

  

+ %if 0%{with_python2}

  %files hub-plugins

  %defattr(-,root,root)

  %dir %{_prefix}/lib/koji-hub-plugins

  %{_prefix}/lib/koji-hub-plugins/*.py*

  %dir /etc/koji-hub/plugins

  %config(noreplace) /etc/koji-hub/plugins/*.conf

+ %endif

  

+ %if 0%{with_python2}

  %files builder-plugins

  %defattr(-,root,root)

  %dir /etc/kojid/plugins

  %config(noreplace) /etc/kojid/plugins/*.conf

  %dir %{_prefix}/lib/koji-builder-plugins

  %{_prefix}/lib/koji-builder-plugins/*.py*

+ %endif

  

+ %if 0%{with_python2}

  %files utils

  %defattr(-,root,root)

  %{_sbindir}/kojira

@@ -357,15 +402,29 @@ 

  %{_sbindir}/koji-shadow

  %dir /etc/koji-shadow

  %config(noreplace) /etc/koji-shadow/koji-shadow.conf

+ %endif

  

- %files web

+ %if 0%{with_python2}

+ %files -n python2-%{name}-web

  %defattr(-,root,root)

  %{_datadir}/koji-web

  %dir /etc/kojiweb

  %config(noreplace) /etc/kojiweb/web.conf

  %config(noreplace) /etc/httpd/conf.d/kojiweb.conf

  %dir /etc/kojiweb/web.conf.d

+ %endif

  

+ %if 0%{with python3}

+ %files -n python%{python3_pkgversion}-%{name}-web

+ %defattr(-,root,root)

+ %{_datadir}/koji-web

+ %dir /etc/kojiweb

+ %config(noreplace) /etc/kojiweb/web.conf

+ %config(noreplace) /etc/httpd/conf.d/kojiweb.conf

+ %dir /etc/kojiweb/web.conf.d

+ %endif

+ 

+ %if 0%{with_python2}

  %files builder

  %defattr(-,root,root)

  %{_sbindir}/kojid

@@ -406,7 +465,9 @@ 

    /sbin/chkconfig --del kojid

  fi

  %endif

+ %endif

  

+ %if 0%{with_python2}

  %files vm

  %defattr(-,root,root)

  %{_sbindir}/kojivmd

@@ -465,6 +526,7 @@ 

    /sbin/chkconfig --del kojira

  fi

  %endif

+ %endif

  

  %changelog

  * Tue May 15 2018 Mike McLean <mikem at redhat.com> - 1.16.0-1

file modified
+5

@@ -2,6 +2,11 @@ 

  Alias /koji "/usr/share/koji-web/scripts/wsgi_publisher.py"

  #(configuration goes in /etc/kojiweb/web.conf)

  

+ # Python 3 Cheetah expectes unicode everywhere, apache's default lang is C

+ # which is not sufficient to open our templates

+ WSGIDaemonProcess koji lang=C.UTF-8

+ WSGIProcessGroup koji

+ 

  <Directory "/usr/share/koji-web/scripts/">

      Options ExecCGI

      SetHandler wsgi-script

file modified
+1 -2

@@ -129,8 +129,7 @@ 

            #end for

            #end if

            #set $arches = $rpmsByArch.keys()

-           #silent $arches.sort()

-           #for $arch in $arches

+           #for $arch in sorted($arches)

            #if $arch == 'src'

            #silent continue

            #end if

file modified
-1

@@ -1,4 +1,3 @@ 

- 

  #from kojiweb import util

  

  #include "includes/header.chtml"

@@ -1,4 +1,4 @@ 

- #encoding utf-8

+ #encoding UTF-8

  #import koji

  #from kojiweb import util

  #import random

file modified
+2 -2

@@ -4,7 +4,7 @@ 

  #include "includes/header.chtml"

  

    <div class="pageHeader">$welcomeMessage</div>

-   

+ 

    <div class="dataHeader noPaginate" id="buildlist">#if $user then 'Your ' else ''#Recent Builds</div>

    <table class="data-list">

      <tr class="list-header">

@@ -36,7 +36,7 @@ 

    </table>

  

    <br/>

-   

+ 

    <div class="dataHeader noPaginate" id="tasklist">#if $user then 'Your ' else ''#Recent Tasks</div>

    <table class="data-list">

      <tr class="list-header">

file modified
+21 -21

@@ -43,7 +43,7 @@ 

  import six

  

  # Convenience definition of a commonly-used sort function

- _sortbyname = kojiweb.util.sortByKeyFunc('name')

+ _sortbyname = lambda x: x['name']

  

  #loggers

  authlogger = logging.getLogger('koji.auth')

@@ -304,7 +304,7 @@ 

                                       start=packageStart, dataName='packages', prefix='package', order=packageOrder, pageSize=10)

  

          notifs = server.getBuildNotifications(user['id'])

-         notifs.sort(kojiweb.util.sortByKeyFunc('id'))

+         notifs.sort(key=lambda x: x['id'])

          # XXX Make this a multicall

          for notif in notifs:

              notif['package'] = None

@@ -898,9 +898,9 @@ 

          tagsByChild[child_id].append(child_id)

  

      srcTargets = server.getBuildTargets(buildTagID=tag['id'])

-     srcTargets.sort(_sortbyname)

+     srcTargets.sort(key=_sortbyname)

      destTargets = server.getBuildTargets(destTagID=tag['id'])

-     destTargets.sort(_sortbyname)

+     destTargets.sort(key=_sortbyname)

  

      values['tag'] = tag

      values['tagID'] = tag['id']

@@ -1108,9 +1108,9 @@ 

      values['title'] = koji.buildLabel(build) + ' | Build Info'

  

      tags = server.listTags(build['id'])

-     tags.sort(_sortbyname)

+     tags.sort(key=_sortbyname)

      rpms = server.listBuildRPMs(build['id'])

-     rpms.sort(_sortbyname)

+     rpms.sort(key=_sortbyname)

      typeinfo = server.getBuildType(buildID)

      archiveIndex = {}

      for btype in typeinfo:

@@ -1365,23 +1365,23 @@ 

          builtInRoot = server.getBuildroot(rpm['buildroot_id'])

      if rpm['external_repo_id'] == 0:

          values['provides'] = server.getRPMDeps(rpm['id'], koji.DEP_PROVIDE)

-         values['provides'].sort(_sortbyname)

+         values['provides'].sort(key=_sortbyname)

          values['obsoletes'] = server.getRPMDeps(rpm['id'], koji.DEP_OBSOLETE)

-         values['obsoletes'].sort(_sortbyname)

+         values['obsoletes'].sort(key=_sortbyname)

          values['conflicts'] = server.getRPMDeps(rpm['id'], koji.DEP_CONFLICT)

-         values['conflicts'].sort(_sortbyname)

+         values['conflicts'].sort(key=_sortbyname)

          values['requires'] = server.getRPMDeps(rpm['id'], koji.DEP_REQUIRE)

-         values['requires'].sort(_sortbyname)

+         values['requires'].sort(key=_sortbyname)

          if koji.RPM_SUPPORTS_OPTIONAL_DEPS:

              values['optional_deps'] = True

              values['recommends'] = server.getRPMDeps(rpm['id'], koji.DEP_RECOMMEND)

-             values['recommends'].sort(_sortbyname)

+             values['recommends'].sort(key=_sortbyname)

              values['suggests'] = server.getRPMDeps(rpm['id'], koji.DEP_SUGGEST)

-             values['suggests'].sort(_sortbyname)

+             values['suggests'].sort(key=_sortbyname)

              values['supplements'] = server.getRPMDeps(rpm['id'], koji.DEP_SUPPLEMENT)

-             values['supplements'].sort(_sortbyname)

+             values['supplements'].sort(key=_sortbyname)

              values['enhances'] = server.getRPMDeps(rpm['id'], koji.DEP_ENHANCE)

-             values['enhances'].sort(_sortbyname)

+             values['enhances'].sort(key=_sortbyname)

          else:

              values['optional_deps'] = False

          headers = server.getRPMHeaders(rpm['id'], headers=['summary', 'description', 'license'])

@@ -1544,10 +1544,10 @@ 

      values['title'] = host['name'] + ' | Host Info'

  

      channels = server.listChannels(host['id'])

-     channels.sort(_sortbyname)

+     channels.sort(key=_sortbyname)

      buildroots = server.listBuildroots(hostID=host['id'],

                                         state=[state[1] for state in koji.BR_STATES.items() if state[0] != 'EXPIRED'])

-     buildroots.sort(kojiweb.util.sortByKeyFunc('-create_event_time'))

+     buildroots.sort(key=lambda x: x['create_event_time'], reverse=True)

  

      values['host'] = host

      values['channels'] = channels

@@ -1603,7 +1603,7 @@ 

  

          values['host'] = host

          allChannels = server.listChannels()

-         allChannels.sort(_sortbyname)

+         allChannels.sort(key=_sortbyname)

          values['allChannels'] = allChannels

          values['hostChannels'] = server.listChannels(hostID=host['id'])

  

@@ -1646,7 +1646,7 @@ 

                               queryOpts={'countOnly': True})

  

      hosts = server.listHosts(channelID=channelID)

-     hosts.sort(_sortbyname)

+     hosts.sort(key=_sortbyname)

  

      values['channel'] = channel

      values['hosts'] = hosts

@@ -1843,7 +1843,7 @@ 

      else:

          values = _initValues(environ, 'Edit Build Target', 'buildtargets')

          tags = server.listTags()

-         tags.sort(_sortbyname)

+         tags.sort(key=_sortbyname)

  

          values['target'] = target

          values['tags'] = tags

@@ -1877,7 +1877,7 @@ 

          values = _initValues(environ, 'Add Build Target', 'builtargets')

  

          tags = server.listTags()

-         tags.sort(_sortbyname)

+         tags.sort(key=_sortbyname)

  

          values['target'] = None

          values['tags'] = tags

@@ -2163,7 +2163,7 @@ 

      if tagObj != None:

          builds = server.listTagged(tagObj['id'], inherit=True, package=(packageObj and packageObj['name'] or None),

                                     owner=(userObj and userObj['name'] or None))

-         builds.sort(kojiweb.util.sortByKeyFunc('-completion_time', noneGreatest=True))

+         builds.sort(key=kojiweb.util.sortByKeyFuncNoneGreatest('completion_time'), reverse=True)

          builds = builds[:20]

      else:

          kwargs = {}

file modified
+3 -3

@@ -1,6 +1,6 @@ 

  #import koji

  #from kojiweb import util

- #import urllib

+ #from six.moves.urllib.parse import quote

  #import cgi

  

  #def printValue($key, $value, $sep=', ')

@@ -424,9 +424,9 @@ 

        <th>Output</th>

        <td>

          #for $volume, $filename in $output

-         <a href="$pathinfo.task($task.id, volume=$volume)/$urllib.quote($filename)">$filename</a>

+         <a href="$pathinfo.task($task.id, volume=$volume)/$quote($filename)">$filename</a>

             #if $filename.endswith('.log')

-            (<a href="getfile?taskID=$task.id&volume=$volume&name=$urllib.quote($filename)&offset=-4000">tail</a>)

+            (<a href="getfile?taskID=$task.id&volume=$volume&name=$quote($filename)&offset=-4000">tail</a>)

             #end if

          <br/>

          #end for

file modified
+11 -5

@@ -184,7 +184,7 @@ 

                  name = 'koji' + name

              elif not name.startswith('koji'):

                  name = 'koji.' + name

-             level_code = logging._levelNames[level]

+             level_code = logging.getLevelName(level)

              logging.getLogger(name).setLevel(level_code)

          logger = logging.getLogger("koji")

          # if KojiDebug is set, force main log level to DEBUG

@@ -350,7 +350,15 @@ 

              ('Content-Length', str(len(result))),

              ('Content-Type', 'text/html'),

          ]

-         return [result], headers

+         return self._tobytes(result), headers

+ 

+     def _tobytes(self, result):

+         if isinstance(result, six.string_types):

+             if six.PY2:

+                 result = [result]

+             else:

+                 result = [bytes(result, encoding='utf-8')]

+         return result

  

      def handle_request(self, environ, start_response):

          if self.startup_error:

@@ -405,9 +413,7 @@ 

          self.logger.debug("Headers:")

          self.logger.debug(koji.util.LazyString(pprint.pformat, [headers]))

          start_response(status, headers)

-         if isinstance(result, six.string_types):

-             result = [result]

-         return result

+         return self._tobytes(result)

  

      def application(self, environ, start_response):

          """wsgi handler"""

file modified
+30 -29

@@ -19,22 +19,24 @@ 

  # Authors:

  #       Mike Bonnet <mikeb@redhat.com>

  #       Mike McLean <mikem@redhat.com>

- 

  from __future__ import absolute_import

  from __future__ import division

+ import cgi

  import Cheetah.Template

  import datetime

  import koji

  from koji.util import md5_constructor

  import os

+ import six

+ import ssl

  import stat

+ 

+ from six.moves import range

  #a bunch of exception classes that explainError needs

  from socket import error as socket_error

- from socket import sslerror as socket_sslerror

  from six.moves.xmlrpc_client import ProtocolError

  from xml.parsers.expat import ExpatError

- import cgi

- from six.moves import range

+ 

  

  class NoSuchException(Exception):

      pass

@@ -97,7 +99,7 @@ 

      def filter(self, *args, **kw):

          """Convert all strs to unicode objects"""

          result = super(DecodeUTF8, self).filter(*args, **kw)

-         if isinstance(result, unicode):

+         if isinstance(result, six.text_type):

              pass

          else:

              result = result.decode('utf-8', 'replace')

@@ -147,7 +149,10 @@ 

          tmpl_class = Cheetah.Template.Template.compile(file=fileName)

          TEMPLATES[fileName] = tmpl_class

      tmpl_inst = tmpl_class(namespaces=[environ['koji.values']], filter=XHTMLFilter)

-     return tmpl_inst.respond().encode('utf-8', 'replace')

+     if six.PY2:

+         return tmpl_inst.respond().encode('utf-8', 'replace')

+     else:

+         return tmpl_inst.respond()

  

  def _truncTime():

      now = datetime.datetime.now()

@@ -243,25 +248,15 @@ 

              passvars.append(var)

      return passthrough(template, *passvars)

  

- def sortByKeyFunc(key, noneGreatest=False):

+ def sortByKeyFuncNoneGreatest(key):

      """Return a function to sort a list of maps by the given key.

-     If the key starts with '-', sort in reverse order.  If noneGreatest

-     is True, None will sort higher than all other values (instead of lower).

+     None will sort higher than all other values (instead of lower).

      """

-     if noneGreatest:

-         # Normally None evaluates to be less than every other value

-         # Invert the comparison so it always evaluates to greater

-         cmpFunc = lambda a, b: (a is None or b is None) and -(cmp(a, b)) or cmp(a, b)

-     else:

-         cmpFunc = cmp

- 

-     if key.startswith('-'):

-         key = key[1:]

-         sortFunc = lambda a, b: cmpFunc(b[key], a[key])

-     else:

-         sortFunc = lambda a, b: cmpFunc(a[key], b[key])

- 

-     return sortFunc

+     def internal_key(obj):

+         v = obj[key]

+         # Nones has priority, others are second

+         return (v is None, v)

+     return internal_key

  

  def paginateList(values, data, start, dataName, prefix=None, order=None, noneGreatest=False, pageSize=50):

      """

@@ -273,7 +268,12 @@ 

      be added to the value map.

      """

      if order != None:

-         data.sort(sortByKeyFunc(order, noneGreatest))

+         if order.startswith('-'):

+             order = order[1:]

+             reverse = True

+         else:

+             reverse = False

+         data.sort(key=sortByKeyFuncNoneGreatest(order), reverse=reverse)

  

      totalRows = len(data)

  

@@ -359,7 +359,7 @@ 

      values[(prefix and prefix + 'Order' or 'order')] = order

      currentPage = start // pageSize

      values[(prefix and prefix + 'CurrentPage' or 'currentPage')] = currentPage

-     totalPages = totalRows // pageSize

+     totalPages = int(totalRows // pageSize)

      if totalRows % pageSize > 0:

          totalPages += 1

      pages = [page for page in range(0, totalPages) if (abs(page - currentPage) < 100 or ((page + 1) % 100 == 0))]

@@ -531,6 +531,9 @@ 

          return value

  

      value = koji.fixEncoding(value)

+     if six.PY3:

+         # it is bytes now, so decode to str

+         value = value.decode()

      return value.replace('&', '&amp;').\

             replace('<', '&lt;').\

             replace('>', '&gt;')

@@ -594,7 +597,7 @@ 

              str = """\

  An error has occurred in the web interface code. This could be due to \

  a bug or a configuration issue."""

-     elif isinstance(error, (socket_error, socket_sslerror)):

+     elif isinstance(error, (socket_error, ssl.SSLError)):

          str = """\

  The web interface is having difficulty communicating with the main \

  server. This most likely indicates a network issue."""

@@ -611,7 +614,7 @@ 

  

  class TaskResultFragment(object):

      """Represent an HTML fragment composed from texts and tags.

-  

+ 

      This class permits us to compose HTML fragment by the default

      composer method or self-defined composer function.

  

@@ -644,7 +647,6 @@ 

              self.empty_str_placeholder = empty_str_placeholder

  

      def default_composer(self, length=None):

-         import cgi

          if length is None:

              text = self.text

          else:

@@ -691,7 +693,6 @@ 

          self.size=self._size()

  

      def default_composer(self, length=None, postscript=None):

-         import cgi

          line_text = ''

          size = 0

          if postscript is None:

Fixes: https://pagure.io/koji/issue/890

For correct work you'll need F28 and/or

python3-cheetach
python3-mod_wsgi

I'm planning to attach spec change with such requires AND conflicts with hub rpm as it supports only py2 for now.

1 new commit added

  • spec changes for python[23]-koji-web
a year ago

I would suggest using C.UTF-8 here.

1 new commit added

  • use C.UTF-8 lang as default
a year ago

rebased onto d33f64d9140a4f1f7997d2da8f682adfe3da6cb6

a year ago

rebased onto 3fe66d34be8f3f27add2291c56c261acf9c2f091

a year ago

Requires: python2-cheetah

This breaks on rhel6/7. Does python2-cheetah in Fedora provide python-cheetah? If so, we could leave the req alone here, if not, we'll need more %if lines.

%package -n python2-%{name}-web

I'm slightly concerned about renaming the -web subpackage without providing the old name.

Is there a reason we can't just build the hub only as Python 3 when it's possible?

rebased onto 85f4a71a39e5cbbb82b8e8db1dbf1cd829b52e52

a year ago

new commit should solve both issues

4 new commits added

  • update provides/requires
  • use C.UTF-8 lang as default
  • Web UI python3 changes
  • spec changes for python[23]-koji-web
a year ago

Why are we building both?! We should just have non-API components build one way or the other.

Good point, but don't we force users (e.g. in older Fedora) to have py3 mod_wsgi even if they've other apps which requires py2? mod_wsgi_python3 can't run in save httpd as mod_wsgi.

Good point, but don't we force users (e.g. in older Fedora) to have py3 mod_wsgi even if they've other apps which require py2? mod_wsgi_python3 can't run in save httpd as mod_wsgi.

My suggestion is to just switch to Python 3 for Fedora 29+. There's an ongoing mass removal for Python 2 packages anyway.

rebased onto 3fe66d34be8f3f27add2291c56c261acf9c2f091

a year ago

rebased onto e9fce625c4523f06b39f1422327b3743f470ae3d

a year ago

Rebased and retested, still works correctly.

I'm concerned about the upgrade path here. The koji-web rpm is renamed to python2-koji-web. The macro seems to automatically provide python-koji-web, but not koji-web. Nothing tells rpm that this package should replace the old koji-web.

Is there a reason we should provide both in this case? It's a web interface application. It'd probably be better to just change it to use Python 3 for fedora, and keep Python 2 for RHEL 6/7.

The code changes themselves generally look ok

1 new commit added

  • macro for py3-only systems
11 months ago

Is there a reason we should provide both in this case? It's a web interface application. It'd probably be better to just change it to use Python 3 for fedora, and keep Python 2 for RHEL 6/7.

An interesting point. You could almost make the same argument for the hub.

Part of the concern is simple caution. Providing both allows a fallback option, and more flexibility for instances to time their transition.

Is there a reason we should provide both in this case? It's a web interface application. It'd probably be better to just change it to use Python 3 for fedora, and keep Python 2 for RHEL 6/7.

An interesting point. You could almost make the same argument for the hub.
Part of the concern is simple caution. Providing both allows a fallback option, and more flexibility for instances to time their transition.

I don't think the concern is warranted. Moreover, we're not going to have much choice soon for Fedora and Mageia (and RHEL 8) anyway. The extra complexity is just not worth it, and to some extent, making it a switch that's activated for everything except RHEL < 8 will help force us make the Python 3 support better.

rebased onto 744216061adf22390e1195ec73b890f62a7950b8

8 months ago

rebased onto 6572dc1414d33c1c334a04fde40e6d09b1e7a921

8 months ago

5 new commits added

  • macro for py3-only systems
  • update provides/requires
  • use C.UTF-8 lang as default
  • spec changes for python[23]-koji-web
  • Web UI python3 changes
8 months ago

rebased onto 861f99b

7 months ago

1 new commit added

  • properly obsolete koji-web
7 months ago

Similar to #921, the spec changes aren't quite where I want them, but I'll create a follow up to address that.

Merging this with a manual rebase (a few spec adjustments to account for the changes in 921)

Commit d54063d fixes this pull-request

Pull-Request has been merged by mikem

7 months ago