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).cute-signatures
parent
a787038dbe
commit
89d003f8c2
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
|
|
||||||
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,
|
|
||||||
opkg->name->name);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Overwriting with permission? */
|
|
||||||
for (i = 0; i < ctx->ipkg->replaces->num; i++)
|
|
||||||
if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg))
|
|
||||||
break;
|
break;
|
||||||
if (i < ctx->ipkg->replaces->num)
|
}
|
||||||
|
}
|
||||||
|
/* Does the new package replace the original one? */
|
||||||
|
for (i = 0; i < ctx->ipkg->replaces->num; i++) {
|
||||||
|
if (apk_dep_is_satisfied(&ctx->ipkg->replaces->item[i], opkg)) {
|
||||||
|
pkg_prio = ctx->ipkg->replaces_priority;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 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,
|
||||||
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:
|
||||||
|
|
Loading…
Reference in New Issue