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}`;
header: gettext('Comment'),
dataIndex: 'Comment',
flex: 2,
+ renderer: Ext.String.htmlEncode,
},
],
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',
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(
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');
product: 'Proxmox VE', // default
errors: [],
suitesWarning: false,
+ mixedSuites: false, // used before major upgrade
subscriptionActive: '',
noSubscriptionRepo: '',
enterpriseRepo: '',
testRepo: '',
+ cephEnterpriseRepo: '',
+ cephNoSubscriptionRepo: '',
+ cephTestRepo: '',
selectionenabled: false,
state: {},
},
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();
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;
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;
+ }
}
}
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);
vm.set('errors', errors);
vm.set('suitesWarning', suitesWarning);
+ vm.set('mixedSuites', mixedSuites);
me.getController().updateState();
});