Automatically filter yum installation platform options based on what's in the repo.
authorDave Page <dpage@pgadmin.org>
Fri, 28 Nov 2025 10:17:49 +0000 (10:17 +0000)
committerDave Page <dpage@pgadmin.org>
Fri, 28 Nov 2025 10:17:49 +0000 (10:17 +0000)
requirements.txt
templates/downloads/js/yum.js
templates/pages/download/linux/redhat.html
tools/ftp/spider_yum.py

index 32042d42a3042fd600da501a0098d09d1f698767..840037ee4f218246da055eeb26c379ac3370ee46 100644 (file)
@@ -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
index ddcff2fd22c9b3d8670fe995c5a6fca01b92ec6d..30e7b51a2eac6acf7d9aa45f81b8ca2450a6d880 100644 (file)
@@ -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();
-}
-
-function verChanged() {
-    /* Just update like the architecture changed */
-    archChanged();
-}
-
-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();
+  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 platChanged() {
-   var plat = document.getElementById('platform').value;
-   var archbox = document.getElementById('arch');
+  const plat = document.getElementById('platform').value;
+  const archbox = document.getElementById('arch');
 
-   while (archbox.options.length > 0) {
-      archbox.options.remove(0);
-   }
+  while (archbox.options.length > 0) {
+    archbox.options.remove(0);
+  }
 
-   if (plat == -1) {
-      archChanged();
-      return;
-   }
+  if (!plat || plat === "-1") {
+    archChanged();
+    return;
+  }
 
-   for (a in repodata['platforms'][plat].sort().reverse()) {
-      var opt = document.createElement('option');
-      opt.text = opt.value = repodata['platforms'][plat][a];
-      archbox.add(opt);
-   }
+ let opt = document.createElement('option');
+ opt.text = '* Select your architecture';
+ opt.value = "-1";
+ archbox.add(opt);
 
-   archChanged();
+  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);
+  }
+
+  archChanged();
 }
 
 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;
+  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
    }
+ }
 
-   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';
-   }
+  for (const a in versions.sort()) {
+    if (supported_versions.includes(parseInt(versions[a]))) {
+      opt = document.createElement('option');
+      opt.text = opt.value = versions[a];
+      verbox.add(opt);
+    }
+  }
 
-   scriptBox.innerHTML += '# Install PostgreSQL:\n';
-   scriptBox.innerHTML += 'sudo ' + installer + ' install -y postgresql' + shortver + '-server\n\n';
+  verChanged();
+}
 
-   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';
-   }
+function verChanged() {
+  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 (!ver || ver === "-1") {
+     document.getElementById('copy-btn').style.display = 'none';
+     scriptBox.innerHTML = 'Select platform, architecture, and version above';
+     return;
+  }
+
+  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';
+  document.getElementById('copy-btn').style.display = 'block';
 }
 
 /* Event handlers */
index 3623bb50000a9436baaa83ce677d74fc6a3bf2ea..e352dccb13e08791e76abaa92de2c05167fc80a0 100644 (file)
@@ -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>
index 2dfa543150908bdef06b4a53e0e2e13043933cd6..1b44e681c7258b089aae47003f708f0370bcd9b9 100755 (executable)
@@ -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})