]> git.proxmox.com Git - proxmox-widget-toolkit.git/blobdiff - src/node/APTRepositories.js
notification: matcher: move match-severity fields to panel
[proxmox-widget-toolkit.git] / src / node / APTRepositories.js
index 1fb627cfa33babf1e9de4d137f131a084cd50139..4e74da20b13e17a518bb20b79b44d9260af6c3e2 100644 (file)
@@ -343,14 +343,15 @@ Ext.define('Proxmox.node.APTRepositoriesGrid', {
            header: gettext('Origin'),
            dataIndex: 'Origin',
            width: 120,
-           renderer: (value, meta, rec) => {
+           renderer: function(value, meta, rec) {
                if (typeof value !== 'string' || value.length === 0) {
                    value = gettext('Other');
                }
                let cls = 'fa fa-fw fa-question-circle-o';
-               if (value.match(/^\s*Proxmox\s*$/i)) {
+               let originType = this.up('proxmoxNodeAPTRepositories').classifyOrigin(value);
+               if (originType === 'Proxmox') {
                    cls = 'pmx-itype-icon pmx-itype-icon-proxmox-x';
-               } else if (value.match(/^\s*Debian\s*(:?Backports)?$/i)) {
+               } else if (originType === 'Debian') {
                    cls = 'pmx-itype-icon pmx-itype-icon-debian-swirl';
                }
                return `<i class='${cls}'></i> ${value}`;
@@ -360,6 +361,7 @@ Ext.define('Proxmox.node.APTRepositoriesGrid', {
            header: gettext('Comment'),
            dataIndex: 'Comment',
            flex: 2,
+           renderer: Ext.String.htmlEncode,
        },
     ],
 
@@ -404,6 +406,16 @@ Ext.define('Proxmox.node.APTRepositories', {
 
     product: 'Proxmox VE', // default
 
+    classifyOrigin: function(origin) {
+       origin ||= '';
+       if (origin.match(/^\s*Proxmox\s*$/i)) {
+           return 'Proxmox';
+       } else if (origin.match(/^\s*Debian\s*(:?Backports)?$/i)) {
+           return 'Debian';
+       }
+       return 'Other';
+    },
+
     controller: {
        xclass: 'Ext.app.ViewController',
 
@@ -449,7 +461,13 @@ Ext.define('Proxmox.node.APTRepositories', {
            let enterprise = vm.get('enterpriseRepo');
            let nosubscription = vm.get('noSubscriptionRepo');
            let test = vm.get('testRepo');
+           let cephRepos = {
+               enterprise: vm.get('cephEnterpriseRepo'),
+               nosubscription: vm.get('cephNoSubscriptionRepo'),
+               test: vm.get('cephTestRepo'),
+           };
            let wrongSuites = vm.get('suitesWarning');
+           let mixedSuites = vm.get('mixedSuites');
 
            if (!enterprise && !nosubscription && !test) {
                addCritical(
@@ -467,17 +485,37 @@ Ext.define('Proxmox.node.APTRepositories', {
                addWarn(gettext('Some suites are misconfigured'));
            }
 
-           if (!activeSubscription && enterprise) {
-               addWarn(gettext('The enterprise repository is enabled, but there is no active subscription!'));
+           if (mixedSuites) {
+               addWarn(gettext('Detected mixed suites before upgrade'));
            }
 
-           if (nosubscription) {
-               addWarn(gettext('The no-subscription repository is not recommended for production use!'));
-           }
+           let productionReadyCheck = (repos, type, noSubAlternateName) => {
+               if (!activeSubscription && repos.enterprise) {
+                   addWarn(Ext.String.format(
+                       gettext('The {0}enterprise repository is enabled, but there is no active subscription!'),
+                       type,
+                   ));
+               }
 
-           if (test) {
-               addWarn(gettext('The test repository may pull in unstable updates and is not recommended for production use!'));
-           }
+               if (repos.nosubscription) {
+                   addWarn(Ext.String.format(
+                       gettext('The {0}no-subscription{1} repository is not recommended for production use!'),
+                       type,
+                       noSubAlternateName,
+                   ));
+               }
+
+               if (repos.test) {
+                   addWarn(Ext.String.format(
+                       gettext('The {0}test repository may pull in unstable updates and is not recommended for production use!'),
+                       type,
+                   ));
+               }
+           };
+
+           productionReadyCheck({ enterprise, nosubscription, test }, '', '');
+           // TODO drop alternate 'main' name when no longer relevant
+           productionReadyCheck(cephRepos, 'Ceph ', '/main');
 
            if (errors.length > 0) {
                text = gettext('Fatal parsing error for at least one repository');
@@ -497,10 +535,14 @@ Ext.define('Proxmox.node.APTRepositories', {
            product: 'Proxmox VE', // default
            errors: [],
            suitesWarning: false,
+           mixedSuites: false, // used before major upgrade
            subscriptionActive: '',
            noSubscriptionRepo: '',
            enterpriseRepo: '',
            testRepo: '',
+           cephEnterpriseRepo: '',
+           cephNoSubscriptionRepo: '',
+           cephTestRepo: '',
            selectionenabled: false,
            state: {},
        },
@@ -610,6 +652,12 @@ Ext.define('Proxmox.node.APTRepositories', {
                vm.set('noSubscriptionRepo', status);
            } else if (handle === 'test') {
                vm.set('testRepo', status);
+           } else if (handle.match(/^ceph-[a-zA-Z]+-enterprise$/)) {
+               vm.set('cephEnterpriseRepo', status);
+           } else if (handle.match(/^ceph-[a-zA-Z]+-no-subscription$/)) {
+               vm.set('cephNoSubscriptionRepo', status);
+           } else if (handle.match(/^ceph-[a-zA-Z]+-test$/)) {
+               vm.set('cephTestRepo', status);
            }
            me.getController().updateState();
 
@@ -631,6 +679,11 @@ Ext.define('Proxmox.node.APTRepositories', {
            let digest;
            let suitesWarning = false;
 
+           // Usually different suites will give errors anyways, but before a major upgrade the
+           // current and the next suite are allowed, so it makes sense to check for mixed suites.
+           let checkMixedSuites = false;
+           let mixedSuites = false;
+
            if (success && records.length > 0) {
                let data = records[0].data;
                let files = data.files;
@@ -649,17 +702,23 @@ Ext.define('Proxmox.node.APTRepositories', {
                        infos[path][idx] = {
                            origin: '',
                            warnings: [],
+                           // Used as a heuristic to detect mixed repositories pre-upgrade. The
+                           // warning is set on all repositories that do configure the next suite.
+                           gotIgnorePreUpgradeWarning: false,
                        };
                    }
 
                    if (info.kind === 'origin') {
                        infos[path][idx].origin = info.message;
-                   } else if (info.kind === 'warning' ||
-                       (info.kind === 'ignore-pre-upgrade-warning' && !repoGrid.majorUpgradeAllowed)
-                   ) {
+                   } else if (info.kind === 'warning') {
                        infos[path][idx].warnings.push(info);
-                   } else {
-                       throw 'unknown info';
+                   } else if (info.kind === 'ignore-pre-upgrade-warning') {
+                       infos[path][idx].gotIgnorePreUpgradeWarning = true;
+                       if (!repoGrid.majorUpgradeAllowed) {
+                           infos[path][idx].warnings.push(info);
+                       } else {
+                           checkMixedSuites = true;
+                       }
                    }
                }
 
@@ -670,11 +729,24 @@ Ext.define('Proxmox.node.APTRepositories', {
                        repo.Path = file.path;
                        repo.Index = n;
                        if (infos[file.path] && infos[file.path][n]) {
-                           repo.Origin = infos[file.path][n].origin || Proxmox.Utils.UnknownText;
+                           repo.Origin = infos[file.path][n].origin || Proxmox.Utils.unknownText;
                            repo.warnings = infos[file.path][n].warnings || [];
 
-                           if (repo.Enabled && repo.warnings.some(w => w.property === 'Suites')) {
-                               suitesWarning = true;
+                           if (repo.Enabled) {
+                               if (repo.warnings.some(w => w.property === 'Suites')) {
+                                   suitesWarning = true;
+                               }
+
+                               let originType = me.classifyOrigin(repo.Origin);
+                               // Only Proxmox and Debian repositories checked here, because the
+                               // warning can be missing for others for a different reason (e.g.
+                               // using 'stable' or non-Debian code names).
+                               if (checkMixedSuites && repo.Types.includes('deb') &&
+                                   (originType === 'Proxmox' || originType === 'Debian') &&
+                                   !infos[file.path][n].gotIgnorePreUpgradeWarning
+                               ) {
+                                   mixedSuites = true;
+                               }
                            }
                        }
                        gridData.push(repo);
@@ -690,6 +762,7 @@ Ext.define('Proxmox.node.APTRepositories', {
 
            vm.set('errors', errors);
            vm.set('suitesWarning', suitesWarning);
+           vm.set('mixedSuites', mixedSuites);
            me.getController().updateState();
        });