Commit 89d003f8 authored by Timo Teräs's avatar Timo Teräs

pkg: introduce "replaces_priority"

If two packages replace each other, the one with highes priority
will keep the file. Additionally, if we have a package overriding
another's file it's remembered and handled properly. This is
essentially to allow "policy packages" which just overwrite certain
(configuration) files from other package(s).
parent a787038d
...@@ -68,6 +68,7 @@ APK_ARRAY(apk_dependency_array, struct apk_dependency); ...@@ -68,6 +68,7 @@ APK_ARRAY(apk_dependency_array, struct apk_dependency);
struct apk_installed_package { struct apk_installed_package {
struct apk_package *pkg; struct apk_package *pkg;
unsigned int flags; unsigned int flags;
unsigned short replaces_priority;
struct list_head installed_pkgs_list; struct list_head installed_pkgs_list;
struct list_head trigger_pkgs_list; struct list_head trigger_pkgs_list;
struct hlist_head owned_dirs; struct hlist_head owned_dirs;
......
...@@ -671,6 +671,10 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo) ...@@ -671,6 +671,10 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
if (ipkg != NULL) if (ipkg != NULL)
apk_blob_pull_deps(&l, db, &ipkg->replaces); apk_blob_pull_deps(&l, db, &ipkg->replaces);
break; break;
case 'q':
if (ipkg != NULL)
ipkg->replaces_priority = apk_blob_pull_uint(&l, 10);
break;
default: default:
if (r != 0 && !(apk_flags & APK_FORCE)) { if (r != 0 && !(apk_flags & APK_FORCE)) {
/* Installed db should not have unsupported fields */ /* Installed db should not have unsupported fields */
...@@ -712,6 +716,11 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os) ...@@ -712,6 +716,11 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
apk_blob_push_deps(&bbuf, ipkg->replaces); apk_blob_push_deps(&bbuf, ipkg->replaces);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n")); apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
} }
if (ipkg->replaces_priority) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("q:"));
apk_blob_push_uint(&bbuf, ipkg->replaces_priority, 10);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
}
hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) { hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:")); apk_blob_push_blob(&bbuf, APK_BLOB_STR("F:"));
...@@ -1780,7 +1789,9 @@ static int read_info_line(void *_ctx, apk_blob_t line) ...@@ -1780,7 +1789,9 @@ static int read_info_line(void *_ctx, apk_blob_t line)
return 0; return 0;
if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) { if (apk_blob_compare(APK_BLOB_STR("replaces"), l) == 0) {
apk_blob_pull_deps(&r, db, &ctx->ipkg->replaces); apk_blob_pull_deps(&r, db, &ipkg->replaces);
} else if (apk_blob_compare(APK_BLOB_STR("replaces_priority"), l) == 0) {
ipkg->replaces_priority = apk_blob_pull_uint(&r, 10);
} else if (apk_blob_compare(APK_BLOB_STR("triggers"), l) == 0) { } else if (apk_blob_compare(APK_BLOB_STR("triggers"), l) == 0) {
apk_string_array_resize(&ipkg->triggers, 0); apk_string_array_resize(&ipkg->triggers, 0);
apk_blob_for_each_segment(r, " ", parse_triggers, ctx->ipkg); apk_blob_for_each_segment(r, " ", parse_triggers, ctx->ipkg);
...@@ -1870,26 +1881,35 @@ static int apk_db_install_archive_entry(void *_ctx, ...@@ -1870,26 +1881,35 @@ static int apk_db_install_archive_entry(void *_ctx,
opkg = file->diri->pkg; opkg = file->diri->pkg;
do { do {
int opkg_prio = -1, pkg_prio = -1;
/* Overlay file? */ /* Overlay file? */
if (opkg->name == NULL) if (opkg->name == NULL)
break; break;
/* Upgrading package? */ /* Upgrading package? */
if (opkg->name == pkg->name) if (opkg->name == pkg->name)
break; break;
/* If we have been replaced, skip file silently. */ /* Does the original package replace the new one? */
for (i = 0; i < opkg->ipkg->replaces->num; i++) { for (i = 0; i < opkg->ipkg->replaces->num; i++) {
if (apk_dep_is_satisfied(&opkg->ipkg->replaces->item[i], pkg)) { if (apk_dep_is_satisfied(&opkg->ipkg->replaces->item[i], pkg)) {
apk_warning("%s: Dropping silently %s owned by %s.", opkg_prio = opkg->ipkg->replaces_priority;
pkg->name->name, ae->name, break;
opkg->name->name);
return 0;
} }
} }
/* Overwriting with permission? */ /* Does the new package replace the original one? */
for (i = 0; i < ctx->ipkg->replaces->num; i++) for (i = 0; i < ctx->ipkg->replaces->num; i++) {
if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg)) if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg)) {
pkg_prio = ctx->ipkg->replaces_priority;
break; break;
if (i < ctx->ipkg->replaces->num) }
}
/* If the original package is more important,
* skip this file */
if (opkg_prio > pkg_prio)
return 0;
/* If the new package has valid 'replaces', we
* will overwrite the file without warnings. */
if (pkg_prio >= 0)
break; break;
if (!(apk_flags & APK_FORCE)) { if (!(apk_flags & APK_FORCE)) {
......
...@@ -708,7 +708,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg, ...@@ -708,7 +708,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
case 'c': case 'c':
pkg->commit = apk_blob_cstr(value); pkg->commit = apk_blob_cstr(value);
break; break;
case 'F': case 'M': case 'R': case 'Z': case 'r': case 'F': case 'M': case 'R': case 'Z': case 'r': case 'q':
/* installed db entries which are handled in database.c */ /* installed db entries which are handled in database.c */
return 1; return 1;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment