Skip to content

Commit

Permalink
apps: Consider ID_LIKE for mapping AppStream data packages
Browse files Browse the repository at this point in the history
With only looking at aos-release's `ID` field, we are missing out a lot
of derivatives, such as CentOS Stream, Rocky, or Debian-likes. Consider
ID_LIKE as well to fix that.

E.g. on Ubuntu, `ID_LIKE` is "debian", on CentOS it's "rhel fedora", on
Rocky Linux it's "rhel centos fedora".

Use that to clean up the manifest map, as Ubuntu and RHEL are now
redundant.

testBasic covers the "direct package name" case in the manifest. Add
a new testOsMap test to check the distroname → packagename map that we
use in real life.

Cherry-picked from 7bbf916
  • Loading branch information
martinpitt committed Dec 12, 2023
1 parent 9f39f65 commit e85b0e5
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 8 deletions.
22 changes: 16 additions & 6 deletions pkg/apps/application-list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,21 @@ export const ApplicationList = ({ metainfo_db, appProgress, appProgressTitle, ac
comps.push(metainfo_db.components[id]);
comps.sort((a, b) => a.name.localeCompare(b.name));

function get_config(name, distro_id, def) {
function get_config(name, os_release, def) {
// ID is a single value, ID_LIKE is a list
const os_list = [os_release.ID || "", ...(os_release.ID_LIKE || "").split(/\s+/)];

if (cockpit.manifests.apps && cockpit.manifests.apps.config) {
let val = cockpit.manifests.apps.config[name];
if (typeof val === 'object' && val !== null && !Array.isArray(val))
val = val[distro_id];
if (typeof val === 'object' && val !== null && !Array.isArray(val)) {
os_list.find(c => {
if (val[c]) {
val = val[c];
return true;
}
return false;
});
}
return val !== undefined ? val : def;
} else {
return def;
Expand All @@ -112,16 +122,16 @@ export const ApplicationList = ({ metainfo_db, appProgress, appProgressTitle, ac
function refresh() {
read_os_release().then(os_release =>
PackageKit.refresh(metainfo_db.origin_files,
get_config('appstream_config_packages', os_release.ID, []),
get_config('appstream_data_packages', os_release.ID, []),
get_config('appstream_config_packages', os_release, []),
get_config('appstream_data_packages', os_release, []),
setProgress))
.finally(() => setProgress(false))
.catch(show_error);
}

let refresh_progress, refresh_button, tbody;
if (progress) {
refresh_progress = <ProgressBar size="sm" title={_("Checking for new applications")} data={progress} />;
refresh_progress = <ProgressBar id="refresh-progress" size="sm" title={_("Checking for new applications")} data={progress} />;
refresh_button = <CancelButton data={progress} />;
} else {
refresh_progress = null;
Expand Down
4 changes: 2 additions & 2 deletions pkg/apps/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@

"config": {
"appstream_config_packages": {
"debian": ["appstream"], "ubuntu": ["appstream"]
"debian": ["appstream"]
},
"appstream_data_packages": {
"fedora": ["appstream-data"], "rhel": ["appstream-data"]
"fedora": ["appstream-data"]
}
}
}
45 changes: 45 additions & 0 deletions test/verify/check-apps
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public License
# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
import time

import packagelib
import testlib
Expand Down Expand Up @@ -129,6 +130,50 @@ class TestApps(packagelib.PackageCase):
def testWithUrlRoot(self):
self.testBasic(urlroot="/webcon")

def testOsMap(self):
b = self.browser
m = self.machine

self.allow_journal_messages("can't remove watch: Invalid argument")

self.restore_dir("/usr/share/metainfo", reboot_safe=True)
self.restore_dir("/usr/share/app-info", reboot_safe=True)
self.restore_dir("/var/cache/app-info", reboot_safe=True)

# Make sure none of the appstream directories exist. They
# will be created later and we need to cope with that.
m.execute("rm -rf /usr/share/metainfo /usr/share/app-info /var/cache/app-info")

# use a fake distro map
self.write_file("/etc/cockpit/apps.override.json",
'{ "config": { "appstream_data_packages":'
' {"testy": ["appstream-data-test"], "otheros": ["nosuchpackage"]}'
' }}')

self.createAppStreamPackage("app-1", "1.0", "1")
self.createAppStreamRepoPackage()

self.login_and_go("/apps")
b.wait_visible(".pf-v5-c-empty-state")

# os-release is a symlink target, don't clobber that
self.restore_file("/etc/os-release")
m.execute("rm /etc/os-release")

# unknown OS: nothing gets installed
m.write("/etc/os-release", 'ID="unmapped"\nID_LIKE="mysterious"\nVERSION_ID="1"\n')
b.click("#refresh")
# the progress bar is too fast to reliably catch it
time.sleep(1)
b.wait_not_present("#refresh-progress")
b.wait_visible(".pf-v5-c-empty-state")

# known OS: appstream-data-tst gets installed from the map
m.write("/etc/os-release", 'ID="derivative"\nID_LIKE="spicy testy"\nVERSION_ID="1"\n')
b.click("#refresh")
with b.wait_timeout(30):
b.wait_visible(".app-list #app-1")

def testL10N(self):
b = self.browser
m = self.machine
Expand Down

0 comments on commit e85b0e5

Please sign in to comment.