public inbox for pgsql-www@postgresql.org  
help / color / mirror / Atom feed
From: Dave Page <dpage@pgadmin.org>
To: Devrim Gündüz <devrim@gunduz.org>
Cc: Jonathan S. Katz <jkatz@postgresql.org>
Cc: Magnus Hagander <magnus@hagander.net>
Cc: pgsql-www <pgsql-www@lists.postgresql.org>
Cc: sysadmins <sysadmins@lists.postgresql.org>
Subject: Re: RPM download page reports incorrect combinations
Date: Wed, 26 Nov 2025 10:29:45 +0000
Message-ID: <CA+OCxoxU-tbgLXGtf=75FCsvJQwronYwAjHzYmkQuF=V04rbKQ@mail.gmail.com> (raw)
In-Reply-To: <edcb4f09a40c72e03a6a65e1a5d11c59ee1f1248.camel@gunduz.org>
References: <12c44268f1abcfe069e923e2b9cd14a6780fd29c.camel@gunduz.org>
	<cbd994f576b6c89e261bada1f601aca8b5652a4c.camel@gunduz.org>
	<c1a1f94f-d6d3-4eb0-9555-3265fa97fd1e@postgresql.org>
	<CA+OCxoyM8O8swU7QfUH=sAEvBAKaMt6V4dyGGt9_M=iyme1oCg@mail.gmail.com>
	<CA+OCxowiE2qsgeBJ5H0avg+aDLC0vtBhJS+P_sZchWS-Ppvwgw@mail.gmail.com>
	<edcb4f09a40c72e03a6a65e1a5d11c59ee1f1248.camel@gunduz.org>

Hi

On Wed, 1 Oct 2025 at 18:50, Devrim Gündüz <devrim@gunduz.org> wrote:

> Hi,
>
> On Thu, 2024-08-08 at 12:00 +0100, Dave Page wrote:
> >
>
> > OK, so I finally got around to attempting to fix this. There are a
> > number of issues to consider:
>
> <snip>
>
> Can someone please review this patch? Currently we claim that PostgreSQL
> 18 is available on RHEL 6.
>

Here's an updated version of the patch, with some minor cleanup (const vs.
var, missing semicolons etc).

Given how long this has been awaiting review, I will commit it on Friday
unless there are technical objections. I will also update the venv package
that pginfra maintains to add rpmfile and zstandard.

-- 
Dave Page
pgAdmin: https://www.pgadmin.org
PostgreSQL: https://www.postgresql.org
pgEdge: https://www.pgedge.com


Attachments:

  [application/octet-stream] yum_version_support_v2.diff (11.1K, 3-yum_version_support_v2.diff)
  download | inline diff:
diff --git a/requirements.txt b/requirements.txt
index 32042d42..840037ee 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,3 +10,5 @@ pynliner==0.8.0
 Babel==2.6.0
 bleach==3.1.4
 PyYAML==3.13
+zstandard==0.23.0
+rpmfile==2.1.0
diff --git a/templates/downloads/js/yum.js b/templates/downloads/js/yum.js
index ddcff2fd..577dc616 100644
--- a/templates/downloads/js/yum.js
+++ b/templates/downloads/js/yum.js
@@ -55,112 +55,135 @@ function uses_systemd(plat) {
 }
 
 function get_platform_text(p) {
-    var a = p.split('-');
+    const a = p.split('-');
     return get_platform_name(a[0], a[1]) + ' version ' + a[1];
 }
 
 window.onload = function() {
-   for (var p in supported_versions) {
-      var opt = document.createElement('option');
-      opt.text = supported_versions[p];
-      document.getElementById('version').add(opt);
-   }
-
-   loadPlatforms();
-   archChanged();
+  const platbox = document.getElementById('platform');
+  const platkeys = Object.keys(repodata['platforms']).sort();
+
+  let opt = document.createElement('option');
+  opt.text = '* Select your platform';
+  opt.value = "-1";
+  platbox.add(opt);
+
+  for (const pp in platkeys) {
+    opt = document.createElement('option');
+    opt.text = get_platform_text(platkeys[pp]);
+    opt.value = platkeys[pp];
+    platbox.add(opt);
+  }
+
+  platChanged();
 }
 
-function verChanged() {
-    /* Just update like the architecture changed */
+function platChanged() {
+  const plat = document.getElementById('platform').value;
+  const archbox = document.getElementById('arch');
+
+  while (archbox.options.length > 0) {
+    archbox.options.remove(0);
+  }
+
+  if (!plat || plat === "-1") {
     archChanged();
-}
+    return;
+  }
 
-function loadPlatforms() {
-   var platbox = document.getElementById('platform');
-
-   while (platbox.options.length > 0) {
-      platbox.options.remove(0);
-   }
-   var opt = document.createElement('option');
-   opt.text = '* Select your platform';
-   opt.value = -1;
-   platbox.add(opt);
-
-   platkeys = Object.keys(repodata['platforms']).sort();
-   for (var pp in platkeys) {
-      var opt = document.createElement('option');
-      opt.text = get_platform_text(platkeys[pp]);
-      opt.value = platkeys[pp];
-      platbox.add(opt);
-   }
-
-   platChanged();
-}
+  let opt = document.createElement('option');
+  opt.text = '* Select your architecture';
+  opt.value = "-1";
+  archbox.add(opt);
 
-function platChanged() {
-   var plat = document.getElementById('platform').value;
-   var archbox = document.getElementById('arch');
+  for (const a in repodata['platforms'][plat].sort((a, b) => a['arch'].localeCompare(b['arch']))) {
+    opt = document.createElement('option');
+    opt.text = opt.value = repodata['platforms'][plat][a]['arch'];
+    archbox.add(opt);
+  }
 
-   while (archbox.options.length > 0) {
-      archbox.options.remove(0);
-   }
+  archChanged();
+}
 
-   if (plat == -1) {
-      archChanged();
-      return;
-   }
+function archChanged() {
+  const plat = document.getElementById('platform').value;
+  const arch = document.getElementById('arch').value;
+  const verbox = document.getElementById('version');
+
+  while (verbox.options.length > 0) {
+    verbox.options.remove(0);
+  }
+
+  if (!arch || arch === "-1") {
+    verChanged();
+    return;
+  }
+
+  let opt = document.createElement('option');
+  opt.text = '* Select your required PostgreSQL version';
+  opt.value = "-1";
+  verbox.add(opt);
+
+  let versions = [];
+  for (const a in repodata['platforms'][plat]) {
+    if (repodata['platforms'][plat][a]['arch'] === arch) {
+      versions = repodata['platforms'][plat][a]['versions'];
+      break;
+    }
+  }
 
-   for (a in repodata['platforms'][plat].sort().reverse()) {
-      var opt = document.createElement('option');
-      opt.text = opt.value = repodata['platforms'][plat][a];
-      archbox.add(opt);
-   }
+  for (const a in versions.sort((a, b) => parseInt(a) - parseInt(b))) {
+    if (supported_versions.includes(parseInt(versions[a]))) {
+      opt = document.createElement('option');
+      opt.text = opt.value = versions[a];
+      verbox.add(opt);
+    }
+  }
 
-   archChanged();
+  verChanged();
 }
 
-function archChanged() {
-   var ver = document.getElementById('version').value;
-   var plat = document.getElementById('platform').value;
-   var arch = document.getElementById('arch').value;
-   var scriptBox = document.getElementById('script-box')
-
-   if (!plat || plat == -1) {
-      document.getElementById('copy-btn').style.display = 'none';
-      scriptBox.innerHTML = 'Select version and platform above';
-      return;
-   }
-
-   var pinfo = repodata['platforms'][plat];
-   var shortver = ver.replace('.', '');
-
-   var url = 'https://download.postgresql.org/pub/repos/yum/reporpms/' + plat + '-' + arch + '/pgdg-' + get_rpm_prefix(plat) +'-repo-latest.noarch.rpm';
-
-   var installer = get_installer(plat);
-   scriptBox.innerHTML = '# Install the repository RPM:\n';
-   scriptBox.innerHTML += 'sudo ' + installer + ' install -y ' + url + '\n\n';
-
-   if (disable_module_on(plat)) {
-      scriptBox.innerHTML += '# Disable the built-in PostgreSQL module:\n';
-      scriptBox.innerHTML += 'sudo dnf -qy module disable postgresql\n\n';
-   }
-
-   scriptBox.innerHTML += '# Install PostgreSQL:\n';
-   scriptBox.innerHTML += 'sudo ' + installer + ' install -y postgresql' + shortver + '-server\n\n';
-
-   scriptBox.innerHTML += '# Optionally initialize the database and enable automatic start:\n';
-   if (uses_systemd(plat)) {
-       var setupcmd = 'postgresql-' + shortver + '-setup';
-       if (ver < 10) {
-	       setupcmd = 'postgresql' + shortver + '-setup';
-       }
-       scriptBox.innerHTML += 'sudo /usr/pgsql-' + ver + '/bin/' + setupcmd + ' initdb\nsudo systemctl enable postgresql-' + ver + '\nsudo systemctl start postgresql-' + ver;
-   }
-   else {
-       scriptBox.innerHTML += 'sudo service postgresql-' + ver + ' initdb\nsudo chkconfig postgresql-' + ver + ' on\nsudo service postgresql-' + ver + ' start';
-   }
-
-   document.getElementById('copy-btn').style.display = 'block';
+function verChanged() {
+  const ver = document.getElementById('version').value;
+  const plat = document.getElementById('platform').value;
+  const arch = document.getElementById('arch').value;
+  const scriptBox = document.getElementById('script-box');
+
+  if (!ver || ver === "-1") {
+     document.getElementById('copy-btn').style.display = 'none';
+     scriptBox.innerHTML = 'Select platform, architecture, and version above';
+     return;
+  }
+
+  const shortver = ver.replace('.', '');
+
+  const url = 'https://download.postgresql.org/pub/repos/yum/reporpms/' + plat + '-' + arch + '/pgdg-' + get_rpm_prefix(plat) +'-repo-latest.noarch.rpm';
+
+  const installer = get_installer(plat);
+  scriptBox.innerHTML = '# Install the repository RPM:\n';
+  scriptBox.innerHTML += 'sudo ' + installer + ' install -y ' + url + '\n\n';
+
+  if (disable_module_on(plat)) {
+    scriptBox.innerHTML += '# Disable the built-in PostgreSQL module:\n';
+    scriptBox.innerHTML += 'sudo dnf -qy module disable postgresql\n\n';
+  }
+
+  scriptBox.innerHTML += '# Install PostgreSQL:\n';
+  scriptBox.innerHTML += 'sudo ' + installer + ' install -y postgresql' + shortver + '-server\n\n';
+
+  scriptBox.innerHTML += '# Optionally initialize the database and enable automatic start:\n';
+  if (uses_systemd(plat)) {
+    let setupcmd = 'postgresql-' + shortver + '-setup';
+    if (ver < 10) {
+      setupcmd = 'postgresql' + shortver + '-setup';
+    }
+    scriptBox.innerHTML += 'sudo /usr/pgsql-' + ver + '/bin/' + setupcmd + ' initdb\nsudo systemctl enable postgresql-' + ver + '\nsudo systemctl start postgresql-' + ver;
+  }
+  else {
+    scriptBox.innerHTML += 'sudo service postgresql-' + ver + ' initdb\nsudo chkconfig postgresql-' + ver + ' on\nsudo service postgresql-' + ver + ' start';
+  }
+
+  document.getElementById('copy-btn').style.display = 'block';
 }
 
 /* Event handlers */
diff --git a/templates/pages/download/linux/redhat.html b/templates/pages/download/linux/redhat.html
index 3623bb50..e352dccb 100644
--- a/templates/pages/download/linux/redhat.html
+++ b/templates/pages/download/linux/redhat.html
@@ -54,9 +54,9 @@ using Fedora for server deployments.
 To use the PostgreSQL Yum Repository, follow these steps:
 </p>
 <ol>
-  <li>Select version: <select id="version" class="custom-select"></select><br/></li>
   <li>Select platform: <select id="platform" class="custom-select"></select></li>
   <li>Select architecture: <select id="arch" class="custom-select"></select></li>
+  <li>Select version: <select id="version" class="custom-select"></select><br/></li>
   <li>Copy, paste and run the relevant parts of the setup script:
     <div class="pg-script-container">
         <pre id="script-box" class="code"></pre>
diff --git a/tools/ftp/spider_yum.py b/tools/ftp/spider_yum.py
index 2dfa5431..3542b638 100755
--- a/tools/ftp/spider_yum.py
+++ b/tools/ftp/spider_yum.py
@@ -5,10 +5,14 @@ import os
 import re
 import json
 import requests
+import rpmfile
 from collections import defaultdict
 from tempfile import NamedTemporaryFile
 
 re_platformdir = re.compile(r'^(\w+)-(\d+)-([^-]+)$')
+re_reporpm = re.compile(r'^pgdg-(\w+)-repo-latest.noarch.rpm$')
+re_repofile = re.compile(r'^./etc/yum.repos.d/pgdg-([a-zA-Z0-9]+)-all.repo$')
+re_reposection = re.compile(r'^\[pgdg([0-9][0-9])]$')
 
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description="Spider repo RPMs")
@@ -21,10 +25,28 @@ if __name__ == "__main__":
     for repodir in os.listdir('{0}/reporpms'.format(args.yumroot)):
         m = re_platformdir.match(repodir)
         if m:
+            # Find the latest repo RPM
+            versions = []
+            path = '{0}/reporpms/{1}'.format(args.yumroot, repodir)
+            for reporpm in os.listdir(path):
+                if re_reporpm.match(reporpm):
+                    with rpmfile.open('{0}/{1}'.format(path, reporpm)) as rpm:
+
+                        # Find the repo config file
+                        for member in rpm.getmembers():
+                            if re_repofile.match(member.name):
+                                fd = rpm.extractfile(member.name)
+                                repos = str(fd.read()).split('\\n')
+
+                                # Get the supported versions
+                                for repo in repos:
+                                    if re_reposection.match(repo):
+                                        versions.append(re_reposection.match(repo).group(1))
+
             platname = m.group(1)
             platver = m.group(2)
             arch = m.group(3)
-            platforms['{0}-{1}'.format(platname, platver)].append(arch)
+            platforms['{0}-{1}'.format(platname, platver)].append({"arch": arch, "versions": versions})
 
     j = json.dumps({'platforms': platforms})
 
@@ -42,7 +64,7 @@ if __name__ == "__main__":
             sys.exit(1)
 
         if r.text != "NOT CHANGED" and r.text != "OK":
-            print("Failed to upload: %s" % x)
+            print("Failed to upload: %s" % r.text)
             sys.exit(1)
     else:
         with NamedTemporaryFile(mode='w', dir=os.path.dirname(os.path.abspath(args.target))) as f:


reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-www@postgresql.org
  Cc: dpage@pgadmin.org, devrim@gunduz.org, jkatz@postgresql.org, magnus@hagander.net, pgsql-www@lists.postgresql.org, sysadmins@lists.postgresql.org
  Subject: Re: RPM download page reports incorrect combinations
  In-Reply-To: <CA+OCxoxU-tbgLXGtf=75FCsvJQwronYwAjHzYmkQuF=V04rbKQ@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox