Browse Source

Version 3 for DPkg::Pre-Install-Pkgs with MultiArch info

Adds on top of Version 2 to all displayed version numbers the
architecture as well as the MultiArch flag for consumption by the hooks.

Most of the time the architecture will be the same for both versions
displayed, but packages might change from "all" to "any" (or back)
between versions so we can't display the architecture for packages.

Pseudo-Format for Version 3:
<name> <version> <arch> <m-a-flag> <compare> <version> <arch> <m-a-flag>

Examples:
stuff - - none < 1 amd64 none **CONFIGURE**
libsame 1 i386 same < 2 i386 same **CONFIGURE**
stuff 2 i386 none > 1 i386 none **CONFIGURE**
libsame 2 i386 same > - - none **REMOVE**
toolkit 1 all foreign > - - none **REMOVE**

Closes: #712116
debian/1.8.y
David Kalnischkies 9 years ago
parent
commit
7a948ec719
  1. 1
      apt-pkg/cacheiterators.h
  2. 71
      apt-pkg/deb/dpkgpm.cc
  3. 4
      apt-pkg/deb/dpkgpm.h
  4. 12
      apt-pkg/pkgcache.cc
  5. 14
      doc/apt.conf.5.xml
  6. 95
      test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch

1
apt-pkg/cacheiterators.h

@ -220,6 +220,7 @@ class pkgCache::VerIterator : public Iterator<Version, VerIterator> {
inline VerFileIterator FileList() const;
bool Downloadable() const;
inline const char *PriorityType() const {return Owner->Priority(S->Priority);};
const char *MultiArchType() const;
std::string RelStr() const;
bool Automatic() const;

71
apt-pkg/deb/dpkgpm.cc

@ -238,15 +238,23 @@ bool pkgDPkgPM::Remove(PkgIterator Pkg,bool Purge)
return true;
}
/*}}}*/
// DPkgPM::SendV2Pkgs - Send version 2 package info /*{{{*/
// DPkgPM::SendPkgInfo - Send info for install-pkgs hook /*{{{*/
// ---------------------------------------------------------------------
/* This is part of the helper script communication interface, it sends
very complete information down to the other end of the pipe.*/
bool pkgDPkgPM::SendV2Pkgs(FILE *F)
{
fprintf(F,"VERSION 2\n");
/* Write out all of the configuration directives by walking the
return SendPkgsInfo(F, 2);
}
bool pkgDPkgPM::SendPkgsInfo(FILE * const F, unsigned int const &Version)
{
// This version of APT supports only v3, so don't sent higher versions
if (Version <= 3)
fprintf(F,"VERSION %u\n", Version);
else
fprintf(F,"VERSION 3\n");
/* Write out all of the configuration directives by walking the
configuration tree */
const Configuration::Item *Top = _config->Tree(0);
for (; Top != 0;)
@ -280,30 +288,51 @@ bool pkgDPkgPM::SendV2Pkgs(FILE *F)
pkgDepCache::StateCache &S = Cache[I->Pkg];
fprintf(F,"%s ",I->Pkg.Name());
// Current version
if (I->Pkg->CurrentVer == 0)
fprintf(F,"- ");
// Current version which we are going to replace
pkgCache::VerIterator CurVer = I->Pkg.CurrentVer();
if (CurVer.end() == true && (I->Op == Item::Remove || I->Op == Item::Purge))
CurVer = FindNowVersion(I->Pkg);
else if (CurVer.end() == true)
{
if (Version <= 2)
fprintf(F, "- ");
else
fprintf(F, "- - none ");
}
else
fprintf(F,"%s ",I->Pkg.CurrentVer().VerStr());
// Show the compare operator
// Target version
{
fprintf(F, "%s ", CurVer.VerStr());
if (Version >= 3)
fprintf(F, "%s %s ", CurVer.Arch(), CurVer.MultiArchType());
}
// Show the compare operator between current and install version
if (S.InstallVer != 0)
{
pkgCache::VerIterator const InstVer = S.InstVerIter(Cache);
int Comp = 2;
if (I->Pkg->CurrentVer != 0)
Comp = S.InstVerIter(Cache).CompareVer(I->Pkg.CurrentVer());
if (CurVer.end() == false)
Comp = InstVer.CompareVer(CurVer);
if (Comp < 0)
fprintf(F,"> ");
if (Comp == 0)
else if (Comp == 0)
fprintf(F,"= ");
if (Comp > 0)
else if (Comp > 0)
fprintf(F,"< ");
fprintf(F,"%s ",S.InstVerIter(Cache).VerStr());
fprintf(F, "%s ", InstVer.VerStr());
if (Version >= 3)
fprintf(F, "%s %s ", InstVer.Arch(), InstVer.MultiArchType());
}
else
fprintf(F,"> - ");
{
if (Version <= 2)
fprintf(F, "> - ");
else
fprintf(F, "> - - none ");
}
// Show the filename/operation
if (I->Op == Item::Install)
{
@ -313,9 +342,9 @@ bool pkgDPkgPM::SendV2Pkgs(FILE *F)
else
fprintf(F,"%s\n",I->File.c_str());
}
if (I->Op == Item::Configure)
else if (I->Op == Item::Configure)
fprintf(F,"**CONFIGURE**\n");
if (I->Op == Item::Remove ||
else if (I->Op == Item::Remove ||
I->Op == Item::Purge)
fprintf(F,"**REMOVE**\n");
@ -404,7 +433,7 @@ bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf)
}
}
else
SendV2Pkgs(F);
SendPkgsInfo(F, Version);
fclose(F);

4
apt-pkg/deb/dpkgpm.h

@ -14,6 +14,7 @@
#include <vector>
#include <map>
#include <stdio.h>
#include <apt-pkg/macros.h>
#ifndef APT_8_CLEANER_HEADERS
using std::vector;
@ -79,7 +80,8 @@ class pkgDPkgPM : public pkgPackageManager
// Helpers
bool RunScriptsWithPkgs(const char *Cnf);
bool SendV2Pkgs(FILE *F);
__deprecated bool SendV2Pkgs(FILE *F);
bool SendPkgsInfo(FILE * const F, unsigned int const &Version);
void WriteHistoryTag(std::string const &tag, std::string value);
// apport integration

12
apt-pkg/pkgcache.cc

@ -924,6 +924,18 @@ string pkgCache::VerIterator::RelStr() const
return Res;
}
/*}}}*/
// VerIterator::MultiArchType - string representing MultiArch flag /*{{{*/
const char * pkgCache::VerIterator::MultiArchType() const
{
if ((S->MultiArch & pkgCache::Version::Same) == pkgCache::Version::Same)
return "same";
else if ((S->MultiArch & pkgCache::Version::Foreign) == pkgCache::Version::Foreign)
return "foreign";
else if ((S->MultiArch & pkgCache::Version::Allowed) == pkgCache::Version::Allowed)
return "allowed";
return "none";
}
/*}}}*/
// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/
// ---------------------------------------------------------------------
/* This stats the file and compares its stats with the ones that were

14
doc/apt.conf.5.xml

@ -688,11 +688,17 @@ DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt";};
will abort. APT will pass the filenames of all .deb files it is going to
install to the commands, one per line on standard input.</para>
<para>Version 2 of this protocol dumps more information, including the
<para>Version 2 of this protocol dumps more information, including the
protocol version, the APT configuration space and the packages, files
and versions being changed. Version 2 is enabled by setting
<literal>DPkg::Tools::options::cmd::Version</literal> to 2. <literal>cmd</literal> is a
command given to <literal>Pre-Install-Pkgs</literal>.</para></listitem>
and versions being changed. Version 3 adds the architecture and <literal>MultiArch</literal>
flag to each version being dumped.</para>
<para>The version of the protocol to be used for the command
<literal><replaceable>cmd</replaceable></literal> can be chosen by setting
<literal>DPkg::Tools::options::<replaceable>cmd</replaceable>::Version</literal>
accordingly, the default being version 1. If APT isn't supporting the requested
version it will send the information in the highest version it has support for instead.
</para></listitem>
</varlistentry>
<varlistentry><term><option>Run-Directory</option></term>

95
test/integration/test-bug-712116-dpkg-pre-install-pkgs-hook-multiarch

@ -0,0 +1,95 @@
#!/bin/sh
set -e
TESTDIR=$(readlink -f $(dirname $0))
. $TESTDIR/framework
setupenvironment
configarchitecture 'amd64' 'i386'
buildsimplenativepackage 'toolkit' 'all' '1' 'stable' 'Multi-Arch: foreign'
buildsimplenativepackage 'toolkit' 'amd64' '2' 'unstable' 'Multi-Arch: foreign'
buildsimplenativepackage 'libsame' 'i386,amd64' '1' 'stable' 'Multi-Arch: same'
buildsimplenativepackage 'libsame' 'i386,amd64' '2' 'unstable' 'Multi-Arch: same'
buildsimplenativepackage 'stuff' 'i386,amd64' '1' 'stable' 'Depends: libsame (= 1), toolkit (= 1)'
buildsimplenativepackage 'stuff' 'i386,amd64' '2' 'unstable' 'Depends: libsame (= 2), toolkit (= 2)'
setupaptarchive
hook='pre-install-pkgs'
enablehookversion() {
echo "#!/bin/sh
while read line; do
if echo \"\$line\" | grep -Fq '**'; then
echo \"\$line\"
fi
done > ${hook}-v${1}.list" > ${hook}-v${1}.sh
chmod +x ${hook}-v${1}.sh
echo "dpkg::${hook}:: \"./${hook}-v${1}.sh --foo -bar\";
DPkg::Tools::options::\"./${hook}-v${1}.sh\"::Version \"$1\";" > rootdir/etc/apt/apt.conf.d/hook-v$1
}
enablehookversion 2
enablehookversion 3
observehook() {
rm -f ${hook}-v2.list ${hook}-v3.list
msgtest 'Observe hooks while' "$*"
aptget "$@" -y --force-yes >/dev/null 2>&1 && msgpass || msgfail
}
observehook install stuff -t stable
testfileequal "${hook}-v2.list" 'libsame - < 1 **CONFIGURE**
toolkit - < 1 **CONFIGURE**
stuff - < 1 **CONFIGURE**'
testfileequal "${hook}-v3.list" 'libsame - - none < 1 amd64 same **CONFIGURE**
toolkit - - none < 1 all foreign **CONFIGURE**
stuff - - none < 1 amd64 none **CONFIGURE**'
observehook install stuff -t unstable
testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
toolkit 1 < 2 **CONFIGURE**
stuff 1 < 2 **CONFIGURE**'
testfileequal "${hook}-v3.list" 'libsame 1 amd64 same < 2 amd64 same **CONFIGURE**
toolkit 1 all foreign < 2 amd64 foreign **CONFIGURE**
stuff 1 amd64 none < 2 amd64 none **CONFIGURE**'
observehook install stuff:i386 -t unstable
testfileequal "${hook}-v2.list" 'stuff 2 > - **REMOVE**
libsame - < 2 **CONFIGURE**
stuff - < 2 **CONFIGURE**'
testfileequal "${hook}-v3.list" 'stuff 2 amd64 none > - - none **REMOVE**
libsame - - none < 2 i386 same **CONFIGURE**
stuff - - none < 2 i386 none **CONFIGURE**'
observehook remove libsame
testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**'
testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**'
observehook install stuff:i386/stable libsame:i386/stable toolkit/stable
testfileequal "${hook}-v2.list" 'libsame 2 > 1 **CONFIGURE**
toolkit 2 > 1 **CONFIGURE**
stuff 2 > 1 **CONFIGURE**'
testfileequal "${hook}-v3.list" 'libsame 2 i386 same > 1 i386 same **CONFIGURE**
toolkit 2 amd64 foreign > 1 all foreign **CONFIGURE**
stuff 2 i386 none > 1 i386 none **CONFIGURE**'
observehook install 'libsame:*'
testfileequal "${hook}-v2.list" 'libsame 1 < 2 **CONFIGURE**
libsame - < 2 **CONFIGURE**
toolkit 1 < 2 **CONFIGURE**
stuff 1 < 2 **CONFIGURE**'
testfileequal "${hook}-v3.list" 'libsame 1 i386 same < 2 i386 same **CONFIGURE**
libsame - - none < 2 amd64 same **CONFIGURE**
toolkit 1 all foreign < 2 amd64 foreign **CONFIGURE**
stuff 1 i386 none < 2 i386 none **CONFIGURE**'
observehook purge stuff:i386 'libsame:*' toolkit
testfileequal "${hook}-v2.list" 'libsame 2 > - **REMOVE**
stuff 2 > - **REMOVE**
libsame 2 > - **REMOVE**
toolkit 2 > - **REMOVE**'
testfileequal "${hook}-v3.list" 'libsame 2 amd64 same > - - none **REMOVE**
stuff 2 i386 none > - - none **REMOVE**
libsame 2 i386 same > - - none **REMOVE**
toolkit 2 amd64 foreign > - - none **REMOVE**'
Loading…
Cancel
Save