We had this code lying around in apt-mark for a while now, but other
frontends need this (and similar) functionality as well, so its high
time that we provide a public interface in libapt for this stuff.
We have a few places and there will be a few more still where we have to
call dpkg to detect/set certain features or settings. Centralizing the
calling infrastructure now seems like a good idea before we add another.
switch 'apt-mark hold' from Pkg to Ver based operation
Users hold a package foo (at version X) or try to prevent the
installation of foo (usually based on the information they know about
version X), even if we say that we "hold a package". Conceptionally we
also need to know about which architecture we are talking and that is an
information bound to a version (as a package can change architecture
over time).
We internally did this lookup from Pkg to Ver already, we just move this
to a central place where the user has a change to influence it now.
add cacheset push_back wrapping for std::back_inserter
As usual by now, not all containers wrapped by the cacheset containers
support all methods, like push_back now, but they fail on use of these
unusable methods only.
Would be nice to not expose these methods for unsupporting containers at
all, but that means either a lot of classes or a lot of std::enable_if
magic, which seems like too big work for this small wrapper for now.
Technically an abi-break as we change a template parameter to
std::iterator for this, but this class is empty in all instances and
just causes the right typedefs to be set – which were incorrect as
detected by std::stable_partition as its implementation uses ::pointer
and needs also a operator* implementation.
In practice CacheSets have no external users (yet) and the difference is
visible only at compile time (which was an error before and now works),
not while linking.
The changes to apt-mark are functionally identical to the code before,
just that we use a std:: algorithm now instead of trying hard on our
own.
Some codepaths need to check if the system (in our case usually dpkg)
supports MultiArch or not. We had copy-pasted the check so far into
these paths, but having it as a system check is better for reusability.
These scripts currently produce HTML output that is directly
piped into an HTML file on alioth.
There are three categories. The first two check external
library calls to use the ones specified by POSIX to be
thread-safe. The main profile excludes functions that are
thread-safe on Linux or glibc in general, while the portable
output strictly follows posix.
The internal.html output lists internal function calls, such
as configuration setting.
This is supposed to be automated further at some point, so
we can automatically check for regressions.
cacheset: Fix compilation on new GCC in C++98 mode
Since gcc 4.9, the API for erase slightly changed. In
commit 3dddcdf2432e78f37c74d8c76c2c519a8d935ab2 the
existing checks for __cplusplus where changed to
check the gcc version, as the __cplusplus check
did nothing, because gcc 4.8 already provided the
standard value in there.
Fix the code to check for the gcc version in two
more places, and change the existing checks to
use a convenience macro.
.travis.yml: Add pinned vivid for gettext and clean up a bit
This adds a vivid pinned to -1, cleans up the file a bit by
removing duplicate commands, and finally installs gettext
with a new apt-get run that is passed -t vivid.
The syntax for the pinning is some weird YAML stuff I don't
want to think about...
tests: add a -j $jobs mode to test runner for parallel execution
Now that tests can be run in parallel, lets actually do it… The mode has
some downsides like not collecting the failed tests, but it can be a lot
faster than a sequential run and is therefore a good alternative in
testing those "this shouldn't break anything" changes (which tend to
break everything if untested).
We uses a small trick to implement the fallback: We make it so, that
by-hash is a special compression algorithm and apt already knows how to
deal with fallback between compression algorithms.
The drawback with implementing this fallback is that a) we are guessing
again and more importantly b) by-hash is only tried for the first
compression algorithm we want to acquire, not for all as before – but
flipping between by-hash and well-known for each compression algorithm
seems to be not really worth it as it seems unlikely that there will
actually be mirrors who only mirror a subset of compressioned files, but
have by-hash enabled.
The user-experience is the usual fallback one: You see "Ign" lines in
the apt update output. The fallback is implemented as a transition
feature, so a (potentially huge) mirror network doesn't need a flagday.
It is not meant as a "someday we might" or "we don't, but some of our
mirrors might" option – we want to cut down on the 'Ign' lines front so
that they become meaningful – if we wanted to spam everyone with them, we
could enable by-hash by default for all repositories…
sources.list and config options are better suited for this.
add by-hash sources.list option and document all of by-hash
This changes the semantics of the option (which is renamed too) to be a
yes/no value with the special additional value "force" as this allows
by-hash to be disabled even if the repository indicates it would be
supported and is more in line with our other yes/no options like pdiff
which disable themselves if no support can be detected.
The feature wasn't documented so far and hasn't reached a (un)stable
release yet, so changing it without trying too hard to keep
compatibility seems okay.
Not all tests work yet, most notable the cdrom tests, but those require
changes in libapt itself to have a proper fix and what we have fixed so
far is good enough progress for now.
deal with spaces in path, command and filepaths in apt-key
Filenames we get could include spaces, but also the tmpdir we work in
and the failures we print in return a very generic and unhelpful…
Properly supporting spaces is a bit painful as we constructed gpg
command before, which is now moved to (multilevel) calls to temporary
scripts instead.
This is mostly a small speedup for the testcases, but it is also handy
to document which tests actually deal with a specific hash compared to
those which 'just' need some hash which can be important while adding
new hashes.
do not report deprecate warnings for the None declaration
This is defined for compatibility, warning about it is intended, but
only in places where it is actually used, rather than at the place we
declare it for compatability…
Setting CXXFLAGS like --coverage on the commandline fails if we set the
std too late, so if we set it with the compiler name we set it always
first. A bit hacky as it bends the expectation, but seems to work.
tests: use more 'native' instead of 'amd64' if possible
The tests usually run on amd64 boxes, but once in a while I run it on a
(slow) armel box as well, which has its fair share of problems with some
tests, but at least the low hanging fruits can be dealt with: Do not
assume that amd64 is the native dpkg architecture – instead use whatever
dpkg thinks is native as architecture for the test.
avoid using global PendingError to avoid failing too often too soon
Our error reporting is historically grown into some kind of mess.
A while ago I implemented stacking for the global error which is used in
this commit now to wrap calls to functions which do not report (all)
errors via return, so that only failures in those calls cause a failure
to propergate down the chain rather than failing if anything
(potentially totally unrelated) has failed at some point in the past.
This way we can avoid stopping the entire acquire process just because a
single source produced an error for example. It also means that after
the acquire process the cache is generated – even if the acquire
process had failures – as we still have the old good data around we can and
should generate a cache for (again).
There are probably more instances of this hiding, but all these looked
like the easiest to work with and fix with reasonable (aka net-positive)
effects.
include debug information in the autoremove-kernels file
Figuring out after the fact what went wrong in the kernel hook is kinda
hart, also as the bugreports are usually very lacking on the details
front. Collecting the internal variables in the debug output we attach
to the generated file might help shine some light on the matter.
It's at least not going to hurt…
do not discard new manual-bits while applying EDSP solutions
In private-install.cc we call MarkInstall with FromUser=true, which sets
the bit accordingly, but while applying the EDSP solution we call mark
install on all packages with FromUser=false, so MarkInstall believes
this install is an automatic one and sets it to auto – so that a new package
which is explicitely installed via an external solver is marked as auto
and is hence also up for garbage collection in a following call.
Ideally MarkInstall wouldn't reset it, but the detection is hard to do
without regressing in other cases – and ideally ideally MarkInstall
wouldn't deal with the autobit at all – so we work around this on the
calling side for now.
implement autobit and pinning in EDSP solver 'apt'
The parser creates a preferences as well as an extended states file
based on the EDSP scenario file, which isn't the most efficient way of
dealing with this as thes text files have to be parsed again by another
layer of the code, but it needs the least changes and works good enough
for now. The 'apt' solver is in the end just a test solver like dump.
These assumptions were once true, but they aren't anymore, so what is
supposed to be a speed up is effectively a slowdown [not that it would
be noticible].
Usage of SingleArchFindPkg was nuked in a stable update already as the
included assumption was actually harmful btw, which is why we should get
right of other 'non-harmful' but still untrue assumptions while we can.
select kernels to protect from autoremove based on Debian version
This is basically a rewrite of the script with the general idea of
finding the Debian version of the installed kernels – as multiple
flavours will have the same Debian version – select the two newest of
them and translate them back to versions found in package names.
This way we avoid e.g. kernel and kernel-rt to use up the protected
slots even through they are basically the same kernel (just a different
flavour) so it is likely that if kernel doesn't work for some reason,
kernel-rt will not either.
This also deals with foreign kernel packages, kernels on hold and partly
installed kernels (in case multiple kernels are installed in the same
apt run) in a hopefully sensible way.
copy ReadWrite-error to the bottom to make clang happy
clang detects that fd isn't set in the ReadWrite case – just that this
is supposed to be catched earlier in this method already, but it doesn't
hurt to make it explicit here as well and clang is happy, too.
As said in the bugreport, this is hardly a serious problem on a security
front, but it was always on the list to have the filename configurable
somehow and the stable filename is a problem for parallel executions.
Using an environment variable (APT_EDSP_DUMP_FILENAME) for this is more
or less the best we can do here as solvers do not get told about our
configuration and such.
Pipes and such have no good Size value, but we still want to copy from
it maybe and we don't really need size as we can just as well read as
long as we get data out of a file to copy it.
The syntax of "Source" is different in EDSP compared to the the field of
the same name in 'the rest' of Debian, so documented this accordingly
and send the version as a new field.
implement dpkgs vision of interpreting pkg:<arch> dependencies
How the Multi-Arch field and pkg:<arch> dependencies interact was
discussed at DebConf15 in the "MultiArch BoF". dpkg and apt (among other
tools like dose) had a different interpretation in certain scenarios
which we resolved by agreeing on dpkg view – and this commit realizes
this agreement in code.
As was the case so far libapt sticks to the idea of trying to hide
MultiArch as much as possible from individual frontends and instead
translates it to good old SingleArch. There are certainly situations
which can be improved in frontends if they know that MultiArch is upon
them, but these are improvements – not necessary changes needed
to unbreak a frontend.
The implementation idea is simple: If we parse a dependency on foo:amd64
the dependency is formed on a package 'foo:amd64' of arch 'any'. This
package is provided by package 'foo' of arch 'amd64', but not by 'foo'
of arch 'i386'. Both of those foo packages provide each other through
(assuming foo is M-A:foreign) to allow a dependency on 'foo' to be
satisfied by either foo of amd64 or i386. Packages can also declare to
provide 'foo:amd64' which is translated to providing 'foo:amd64:any' as
well.
This indirection over provides was chosen as the alternative would be to
teach dependency resolvers how to deal with architecture specific
dependencies – which violates the design idea of avoiding resolver
changes, especially as architecture-specific dependencies are a
cornercase with quite a few subtil rules. Handling it all over versioned
provides as we already did for M-A in general seems much simpler as it
just works for them.
This switch to :any has actually a "surprising" benefit as well: Even
frontends showing a package name via .Name() [which doesn't show the
architecture] will display the "architecture" for dependencies in which
it was explicitely requested, while we will not show the 'strange' :any
arch in FullName(true) [= pretty-print] either. Before you had to
specialcase these and by default you wouldn't get these details shown.
The only identifiable disadvantage is that this complicates error
reporting and handling. apt-get's ShowBroken has existing problems with
virtual packages [it just shows the name without any reason], so that
has to be worked on eventually. The other case is that detecting if a
package is completely unknown or if it was at least referenced somewhere
needs to acount for this "split" – not that it makes a practical
difference which error is shown… but its one of the improvements
possible.
M-A: allowed pkgs of unconfigured archs do not statisfy :any
We parse all architectures we encounter recently, which means we also
parse packages from architectures which are neither native nor foreign,
but still came onto the system somehow (usually via heavy force).
store ':any' pseudo-packages with 'any' as architecture
Previously we had python:any:amd64, python:any:i386, … in the cache and
the dependencies of an amd64 package would be on python:any:amd64, of an
i386 on python:any:i386 and so on. That seems like a relatively
pointless endeavor given that they will all be provided by the same
packages and therefore also a waste of space.
Michael Vogt [Fri, 4 Sep 2015 21:29:38 +0000 (23:29 +0200)]
Add support for writing by-hash dirs in apt-ftparchive
This option is enabled via the APT::FTPArchive::DoByHash switch.
It will also honor the option APT::FTPArchive::By-Hash-Keep that
controls how many previous generation of by-hash files should be
kept (defaults to 3).
Merged from https://github.com/mvo5/apt/tree/feature/apt-ftparchive-by-hash
Initializing a random number generator with the time since epoch could
be good enough, but reaches its limits in test code as the 100
iterations might very well happen in the same second and hence the seed
number is always the same… clock() has a way lower resolution so it
changes more often and not unimportant: If many users start the update
at the same time it isn't to unlikely the SRV record will be ordered in
the same second choosing the same for them all, but it seems less likely
that the exact same clock() time has passed for them.
And if I have to touch this, lets change a few other things as well to
make me and/or compilers a bit happier (clang complained about the usage
of a GNU extension in the testcase for example).
use unusable-for-security hashes for integrity checks
We want to declare some hashes as not enough for security, so that a
user will need --allow-unauthenticated or similar to get data secured
only by those hashes, but we can still us these hashes for integrity
checks if we got them.
test: show the highlevel test for lowerranking ones
testsuccess checks the return code, but it does also some autotests
based on the command like grepping for dpkg warnings in a apt-get
install call – but if this finds something it is just showing the grep
command. With this change it will additionally show the first msgtest
which in this case will detail the actual apt-get install call.
tests: store msgtest in -q mode for display in msgfail
Not-quiet output is very verbose and with our growing array of tests
generates many many lines which e.g. kills the log display in travis-ci
and obscures failures and uncatched output in a wall of details.
The -q mode fixed this by callapsing passed tests to a single P and now
with some rework we can even get failures properly displayed with the
message from msgtest.
do delay the test for http, too, to make it more reliable
The file method was already slowed down and somehow I thought I had done
the same for http, but it turns out that I didn't. Giving it the same
delay as file should help in making this test slower and therefore more
likely to successfully test what it is supposed to test.
if file is inaccessible for _apt, disable privilege drop in acquire
We had a very similar method previously for our own private usage, but
with some generalisation we can move this check into the acquire system
proper so that all frontends profit from this compatibility change.
As we are disabling a security feature here a warning is issued and
frontends are advised to consider reworking their download logic if
possible.
Note that this is implemented as an all or nothing situation: We can't
just (not) drop privileges for a subset of the files in a fetcher, so in
case you have to download some files with and some without you need to
use two fetchers.
ignore for _apt inaccessible TMPDIR in pkgAcqChangelog
Using libpam-tmpdir caused us to create our download tmp directory in
root's private tmp before changing to _apt, which wouldn't have access
to it.
By extending our GetTempDir method with an optional wrapper changing the
effective user, we can test if a given user can access the directory and
ignore TMPDIR if not instead of ignoring TMPDIR completely.
Multiple targets downloading the same file is bad™ as it leads us to all
sorts of problems like the acquire system breaking or simply a problem
of which settings to use for them. Beside that this is most likely a
mistake and silently ignoring it doesn't help the user realizing his
mistake…
On the other hand, we have 'duplicates' which are 'created' by how we
create indextargets, so we have to prevent those from being created to
but do not emit a warning for them as this is an implementation detail.
And then, there is the absolute and most likely user mistake: Having the
same target(s) activated in multiple entries.
xz has pretty much won "the compressor war" and e.g. the Debian archive
doesn't even distribute bz2 anymore in favor of 'xz' and 'gz', so by
changing the default order we have a more realistic --print-uris
behavior as it will always show the first compressor.
In practice this effects repositories without a Release file (very bad,
we don't want to support them anymore anyhow) as xz will be tried before
bz2 now [which is probably not available, but so might be bz2…] AND
repositories which provide both, bz2 and xz (which isn't too common) in
sofar as apt will now download xz instead of bz2.
Users with special needs can stick with bz2 as first compressor tried
with Acquire::CompressionTypes::Order:: "bz2"; (see man apt.conf) – but
users with special needs usually prefer "gz" anyhow, so the realworld
change is expected to be very low.
Some targets like Contents-udeb are special-needs targets. Shipping the
configuration snippet for them is okay, but they shouldn't be downloaded
by default. Forcing the user to enable targets by uncommenting targets
is wrong and this would still not really solve the problem completely as
even if you want to download some -udebs it will probably not be for all
sources you have enabled, so having the possibility of disabling a
target by default, but giving the user the option to enable it on a
per-source entry basis is better.