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

Bug#767891: apt: Provide ability to manually mark packages as "essential"



Package: apt
Version: 1.0.9.3
Severity: wishlist
Tags: patch

Hi,

It would be useful to be able to locally mark certain packages as
"Essential:yes" so that they are never uninstalled. Trivial example: mark
sysvinit-core as essential on systems you don't want to have upgraded
to systemd as init.

I'm including a patch that allows you to do this by:

$ sudo apt-get -o pkgCacheGen::ForceEssential=systemd-sysv,apt update
...
$ sudo apt-get install sysvinit-core
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  systemd-sysv
The following NEW packages will be installed:
  sysvinit-core
WARNING: The following essential packages will be removed.
This should NOT be done unless you know exactly what you are doing!
  systemd-sysv
0 upgraded, 1 newly installed, 1 to remove and 304 not upgraded.
Need to get 0 B/130 kB of archives.
After this operation, 179 kB of additional disk space will be used.
You are about to do something potentially harmful.
To continue type in the phrase 'Yes, do as I say!'
 ?] no
Abort.

versus:

$ sudo apt-get -o pkgCacheGen::ForceEssential=apt update
...
$ sudo apt-get install sysvinit-core
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following packages will be REMOVED:
  systemd-sysv
The following NEW packages will be installed:
  sysvinit-core
0 upgraded, 1 newly installed, 1 to remove and 304 not upgraded.
Need to get 0 B/130 kB of archives.
After this operation, 179 kB of additional disk space will be used.
Do you want to continue? [Y/n] n
Abort.


Patch is (git diff -b, ignoring whitespace-only changes):

--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -277,13 +277,20 @@ bool debListParser::UsePackage(pkgCache::PkgIterator &Pkg,
    if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false)
       return false;
 
-   if (strcmp(Pkg.Name(),"apt") == 0)
+   std::vector<std::string> force_essential = _config->FindVector("pkgCacheGen::ForceEssential","apt");
+   for (std::vector<std::string>::const_iterator p = force_essential.begin(); p != force_essential.end(); ++p)
+   {
+      if (strcmp(p->c_str(), Pkg.Name()) == 0)
       {
          if ((essential == "native" && Pkg->Arch != 0 && myArch == Pkg.Arch()) ||
              essential == "all")
             Pkg->Flags |= pkgCache::Flag::Essential | pkgCache::Flag::Important;
          else
             Pkg->Flags |= pkgCache::Flag::Important;
+
+         _error->Notice("Marking package as essential: %s",p->c_str());
+
+      }
    }
 
    if (ParseStatus(Pkg,Ver) == false)

Cheers,
aj


Reply to: