[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[RFC/dpkg PATCH] Introducing an relaxed-Essential-like "Important" field



Since a few years, APT supports an "Important" field that is similar
to Essential, but without the requirement for those packages to be
installed (they just need to remain installed) and the ordering
constraints. Previously, it was already an alias for Essential in
APT.

I relaxed the meaning a few years ago to make it suitable for use
on site-specific or system-specific configuration meta packages.

I propose to make this field official and add support to dpkg
for it, as there are new use cases for it, like init systems,
e2fsprogs, and mount - packages that are not needed on all 
systems (like chroots), but once installed should probably
remain installed.

I attached a patch to add support for dpkg, it's also discussed
in a spec in the wiki.

I'd like some feedback.

References:

[1] https://wiki.debian.org/Teams/Dpkg/Spec/ImportantField

-- 
Debian Developer - deb.li/jak | jak-linux.org - free software dev

When replying, only quote what is necessary, and write each reply
directly below the part(s) it pertains to (`inline'). Thank you.
>From 141931815cdf663aab5ecccf6b4fdd517f99cbd4 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <jak@debian.org>
Date: Sun, 6 Mar 2016 00:55:31 +0100
Subject: [PATCH] Add support for the "Important" field

The important field is like essential, but imposes less
requirements.

See: https://wiki.debian.org/Teams/Dpkg/Spec/ImportantField
---
 debian/changelog                   |  3 +++
 lib/dpkg/dpkg-db.h                 |  1 +
 lib/dpkg/parse.c                   |  1 +
 lib/dpkg/pkg.c                     |  1 +
 man/deb-control.5                  |  6 ++++++
 man/dpkg.1                         |  5 +++++
 scripts/Dpkg/Control/FieldsCore.pm |  3 +++
 src/archives.c                     | 16 +++++++++++++++-
 src/main.c                         |  3 +++
 src/main.h                         |  1 +
 src/remove.c                       |  4 ++++
 src/select.c                       |  2 +-
 src/unpack.c                       |  1 +
 13 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 546cff5..92cca7b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -95,6 +95,9 @@ dpkg (1.18.5) UNRELEASED; urgency=medium
   * Simplified Chinese (Zhou Mo). Closes: #809517
   * Vietnamese (Trần Ngọc Quân).
 
+  [ Julian Andres Klode ]
+  * Add support for the "Important" field
+
  -- Guillem Jover <guillem@debian.org>  Fri, 25 Dec 2015 14:20:16 +0100
 
 dpkg (1.18.4) unstable; urgency=medium
diff --git a/lib/dpkg/dpkg-db.h b/lib/dpkg/dpkg-db.h
index 389aaad..4748854 100644
--- a/lib/dpkg/dpkg-db.h
+++ b/lib/dpkg/dpkg-db.h
@@ -108,6 +108,7 @@ struct pkgbin {
   struct dependency *depends;
   /** The ‘essential’ flag, true = yes, false = no (absent). */
   bool essential;
+  bool important;
   enum pkgmultiarch multiarch;
   const struct dpkg_arch *arch;
   /** The following is the "pkgname:archqual" cached string, if this was a
diff --git a/lib/dpkg/parse.c b/lib/dpkg/parse.c
index 2d7f0a3..150b4a7 100644
--- a/lib/dpkg/parse.c
+++ b/lib/dpkg/parse.c
@@ -54,6 +54,7 @@ const struct fieldinfo fieldinfos[]= {
   /* Note: Capitalization of field name strings is important. */
   { FIELD("Package"),          f_name,            w_name                                     },
   { FIELD("Essential"),        f_boolean,         w_booleandefno,   PKGIFPOFF(essential)     },
+  { FIELD("Important"),        f_boolean,         w_booleandefno,   PKGIFPOFF(important)     },
   { FIELD("Status"),           f_status,          w_status                                   },
   { FIELD("Priority"),         f_priority,        w_priority                                 },
   { FIELD("Section"),          f_section,         w_section                                  },
diff --git a/lib/dpkg/pkg.c b/lib/dpkg/pkg.c
index 1fc3d0c..7fe8ad8 100644
--- a/lib/dpkg/pkg.c
+++ b/lib/dpkg/pkg.c
@@ -96,6 +96,7 @@ void
 pkgbin_blank(struct pkgbin *pkgbin)
 {
 	pkgbin->essential = false;
+	pkgbin->important = false;
 	pkgbin->depends = NULL;
 	pkgbin->pkgname_archqual = NULL;
 	pkgbin->description = NULL;
diff --git a/man/deb-control.5 b/man/deb-control.5
index fea726c..8cbaebe 100644
--- a/man/deb-control.5
+++ b/man/deb-control.5
@@ -98,6 +98,12 @@ a package that is required for proper operation of the system. Dpkg
 or any other installation tool will not allow an
 .B Essential
 package to be removed (at least not without using one of the force options).
+.BR Important: " \fByes\fP|\fBno\fP"
+This field is usually only needed when the answer is \fByes\fP. It denotes
+a package that should not be removed from a system. Dpkg
+or any other installation tool will not allow an
+.B Important
+package to be removed (at least not without using one of the force options).
 .TP
 .BR Build\-Essential: " \fByes\fP|\fBno\fP"
 This field is usually only needed when the answer is \fByes\fP, and is
diff --git a/man/dpkg.1 b/man/dpkg.1
index cdfbe2b..e7efecb 100644
--- a/man/dpkg.1
+++ b/man/dpkg.1
@@ -528,6 +528,11 @@ remain on the system, which will then be forgotten by \fBdpkg\fP.
 Remove, even if the package is considered essential. Essential
 packages contain mostly very basic Unix commands. Removing them might
 cause the whole system to stop working, so use with caution.
+\fBremove\-important\fP:
+Remove, even if the package is considered important. Important
+packages contain things relevant to specific system configurations (for example,
+init systems on systems that will be booted).
+Removing them might cause the whole system to stop working, so use with caution.
 
 \fBdepends\fP:
 Turn all dependency problems into warnings.
diff --git a/scripts/Dpkg/Control/FieldsCore.pm b/scripts/Dpkg/Control/FieldsCore.pm
index 3af6fa7..fe39d65 100644
--- a/scripts/Dpkg/Control/FieldsCore.pm
+++ b/scripts/Dpkg/Control/FieldsCore.pm
@@ -227,6 +227,9 @@ our %FIELDS = (
     'Homepage' => {
         allowed => ALL_SRC | ALL_PKG,
     },
+    'Important' => {
+        allowed => ALL_PKG,
+    },
     'Installed-Size' => {
         allowed => ALL_PKG & ~CTRL_INFO_PKG,
     },
diff --git a/src/archives.c b/src/archives.c
index ae7fa30..ffc6012 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -1235,6 +1235,18 @@ try_deconfigure_can(bool (*force_p)(struct deppossi *), struct pkginfo *pkg,
         return 0;
       }
     }
+    if (pkg->installed.important) {
+      if (fc_removeimportant) {
+        warning(_("considering deconfiguration of important\n"
+                  " package %s, to enable %s"),
+                pkg_name(pkg, pnaw_nonambig), action);
+      } else {
+        notice(_("no, %s is important, will not deconfigure\n"
+                 " it in order to enable %s"),
+               pkg_name(pkg, pnaw_nonambig), action);
+        return 0;
+      }
+    }
     enqueue_deconfigure(pkg, removal);
     return 1;
   } else {
@@ -1329,10 +1341,12 @@ void check_conflict(struct dependency *dep, struct pkginfo *pkg,
       ensure_package_clientdata(fixbyrm);
     }
     if (((pkg->available.essential && fixbyrm->installed.essential) ||
+         (pkg->available.important && fixbyrm->installed.important) ||
          (((fixbyrm->want != PKG_WANT_INSTALL &&
             fixbyrm->want != PKG_WANT_HOLD) ||
            does_replace(pkg, &pkg->available, fixbyrm, &fixbyrm->installed)) &&
-          (!fixbyrm->installed.essential || fc_removeessential)))) {
+          (!fixbyrm->installed.essential || fc_removeessential) &&
+          (!fixbyrm->installed.important || fc_removeimportant)))) {
       assert(fixbyrm->clientdata->istobe == PKG_ISTOBE_NORMAL ||
              fixbyrm->clientdata->istobe == PKG_ISTOBE_DECONFIGURE);
       fixbyrm->clientdata->istobe = PKG_ISTOBE_REMOVE;
diff --git a/src/main.c b/src/main.c
index cd4211b..80083f8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -196,6 +196,7 @@ int fc_conff_ask = 0;
 int fc_unsafe_io = 0;
 int fc_badverify = 0;
 int fc_badversion = 0;
+int fc_removeimportant = 0;
 
 int errabort = 50;
 static const char *admindir = ADMINDIR;
@@ -275,6 +276,8 @@ static const struct forceinfo {
     '!', N_("Remove packages which require installation") },
   { "remove-essential",    &fc_removeessential,
     '!', N_("Remove an essential package") },
+  { "remove-important",    &fc_removeimportant,
+    '!', N_("Remove an important package") },
   { NULL }
 };
 
diff --git a/src/main.h b/src/main.h
index b7c1db7..54a4b7d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -141,6 +141,7 @@ extern int fc_conff_ask;
 extern int fc_badverify;
 extern int fc_badversion;
 extern int fc_unsafe_io;
+extern int fc_removeimportant;
 
 extern bool abort_processing;
 extern int errabort;
diff --git a/src/remove.c b/src/remove.c
index b5cb996..204b514 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -122,6 +122,9 @@ void deferred_remove(struct pkginfo *pkg) {
   if (pkg->installed.essential && pkg->status != PKG_STAT_CONFIGFILES)
     forcibleerr(fc_removeessential,
                 _("this is an essential package; it should not be removed"));
+  if (pkg->installed.important && pkg->status != PKG_STAT_CONFIGFILES)
+    forcibleerr(fc_removeimportant,
+                _("this is an important package; it should not be removed"));
 
   debug(dbg_general, "checking dependencies for remove '%s'",
         pkg_name(pkg, pnaw_always));
@@ -364,6 +367,7 @@ removal_bulk_remove_files(struct pkginfo *pkg)
 
     pkg_set_status(pkg, PKG_STAT_CONFIGFILES);
     pkg->installed.essential = false;
+    pkg->installed.important = false;
     modstatdb_note(pkg);
     push_checkpoint(~ehflag_bombout, ehflag_normaltidy);
 }
diff --git a/src/select.c b/src/select.c
index 1f0d4df..4da1907 100644
--- a/src/select.c
+++ b/src/select.c
@@ -224,7 +224,7 @@ clearselections(const char *const *argv)
 
   iter = pkg_db_iter_new();
   while ((pkg = pkg_db_iter_next_pkg(iter))) {
-    if (!pkg->installed.essential)
+    if (!pkg->installed.essential && !pkg->installed.important)
       pkg_set_want(pkg, PKG_WANT_DEINSTALL);
   }
   pkg_db_iter_free(iter);
diff --git a/src/unpack.c b/src/unpack.c
index 8d10cc5..332074c 100644
--- a/src/unpack.c
+++ b/src/unpack.c
@@ -762,6 +762,7 @@ pkg_update_fields(struct pkginfo *pkg, struct filenamenode_queue *newconffiles)
 
   /* We copy the text fields. */
   pkg->installed.essential = pkg->available.essential;
+  pkg->installed.important = pkg->available.important;
   pkg->installed.multiarch = pkg->available.multiarch;
   pkg->installed.description = pkg->available.description;
   pkg->installed.maintainer = pkg->available.maintainer;
-- 
2.7.0


Reply to: