piuparts-0.64ubuntu1/ 0000775 0000000 0000000 00000000000 12604570246 011534 5 ustar piuparts-0.64ubuntu1/update-piuparts-slave-setup 0000775 0000000 0000000 00000004610 12514657214 017061 0 ustar #!/bin/sh
set -e
#
# update piuparts slave setup from git (eg. used on piu-slave-bm-a.debian.org)
#
# Copyright 2009-2013 Holger Levsen (holger@layer-acht.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
if [ "`id -n -u`" != "piupartss" ] ; then
echo please run this script as piupartss user
exit 1
fi
PIUPARTS_PREFIX=/srv/piuparts.debian.org
PIUPARTS_HTDOCS=$PIUPARTS_PREFIX/htdocs
PIUPARTS_TMPDIR=$PIUPARTS_PREFIX/tmp
#
# create $PIUPARTS_PREFIX
#
if [ ! -d $PIUPARTS_PREFIX ] ; then
sudo mkdir -p $PIUPARTS_PREFIX
sudo chown piupartss:piuparts $PIUPARTS_PREFIX
sudo chmod 0775 $PIUPARTS_PREFIX
fi
#
# update source
#
if [ ! -d $PIUPARTS_PREFIX/src ] ; then
mkdir -p $PIUPARTS_PREFIX/src
chmod 0755 $PIUPARTS_PREFIX/src
cd $PIUPARTS_PREFIX/src
git clone git://git.debian.org/git/piuparts/piuparts.git
cd piuparts
git checkout develop
fi
cd $PIUPARTS_PREFIX/src/piuparts
pwd
# git checkout branch if $1 is given
if [ ! -z "$1" ] ; then
git checkout $1
fi
# git fetch+pull if $2 is given
if [ ! -z "$2" ] ; then
git fetch $2
git pull $2 $1
fi
#
# install everything from GIT into PIUPARTS_PREFIX
#
make clean
make prefix=$PIUPARTS_PREFIX \
build build-doc
make prefix=$PIUPARTS_PREFIX \
docdir=$PIUPARTS_HTDOCS/doc \
htdocsdir=$PIUPARTS_HTDOCS \
install install-doc install-conf-4-running-from-git
make clean
#
# update $PIUPARTS_PREFIX
#
cd $PIUPARTS_PREFIX
pwd
mkdir -p slave slave/basetgz
# to support multiple hosts with this setup
cd etc/piuparts
HOSTNAME=$(hostname)
for f in piuparts.conf
do
ln -sf $f.$HOSTNAME $f
done
#
# create working dir
#
mkdir -p $PIUPARTS_TMPDIR
#
# update slave home
#
cd
pwd
ln -sf $PIUPARTS_PREFIX/share/piuparts/slave bin
crontab $PIUPARTS_PREFIX/etc/piuparts/crontab-slave
echo "Update finished."
piuparts-0.64ubuntu1/tests/ 0000775 0000000 0000000 00000000000 12536542721 012677 5 ustar piuparts-0.64ubuntu1/tests/test_dependencyparser.py 0000664 0000000 0000000 00000001701 12514675664 017653 0 ustar import unittest
import piupartslib.dependencyparser
class DependencyParserTests(unittest.TestCase):
"""Tests for module dependencyparser."""
def parse(self, str):
parser = piupartslib.dependencyparser.DependencyParser(str)
deps = parser.get_dependencies()
names = []
for dep in deps:
names.append([])
for simpledep in dep:
names[-1].append(simpledep.name)
return deps, names
def testEmpty(self):
deps, names = self.parse("")
self.failUnlessEqual(deps, [])
def testSingle(self):
deps, names = self.parse("foo")
self.failUnlessEqual(names, [["foo"]])
def testTwo(self):
deps, names = self.parse("foo, bar")
self.failUnlessEqual(names, [["foo"], ["bar"]])
def testAlternatives(self):
deps, names = self.parse("foo, bar | foobar")
self.failUnlessEqual(names, [["foo"], ["bar", "foobar"]])
piuparts-0.64ubuntu1/tests/README 0000664 0000000 0000000 00000001221 12452567512 013555 0 ustar To get discovered by nosetests the python files in this directory must be named
test_.py.
The test case classes should be named 'NameOfTheClassUnderTestTests' and the
test functions should be named 'test_functionundertest_expected_bahavior' e.g.:
# foobar.py
-----
class FooBar(object):
def baz(self):
return 'baz
-----
# tests/test_foobar.py
-----
class FooBarTests(unittest.Testcase):
def setUp(self):
self.fb = FooBar()
def test_baz_should_return_baz(self):
ret_val = self.fb.baz()
self.assertEqual(ret_val, 'baz')
-----
Use pymox as mocking framework if needed.
apt-get install python-mox3
piuparts-0.64ubuntu1/tests/unittests.py 0000664 0000000 0000000 00000003642 12525654513 015321 0 ustar # -*- coding: utf-8 -*-
import os
import StringIO
import unittest
import piupartslib.packagesdb
class FakeLogDB(piupartslib.packagesdb.LogDB):
"""A fake version of the LogDB class, for testing
This version simulates filesystem actions so that there is no need
to do actual I/O. Cleaner, although not quite as thorough.
"""
def __init__(self):
self.dict = {
"pass": [],
"fail": [],
"untestable": [],
"reserved": [],
"bugged": [],
"affected": [],
}
def listdir(self, dirname):
return self.dict[dirname]
def _parse(self, pathname):
return os.path.dirname(pathname), os.path.basename(pathname)
def exists(self, pathname):
vdir, base = self._parse(pathname)
return base in self.dict[vdir]
def open_file(self, pathname, mode):
vdir, base = self._parse(pathname)
self.dict[vdir].append(base)
return StringIO.StringIO()
def remove_file(self, pathname):
vdir, base = self._parse(pathname)
if base in self.dict[vdir]:
del self.dict[vdir]
def create(self, subdir, package, version, contents):
return True
class PackagesDbTests(unittest.TestCase):
def new_db(self, packages_file_contents):
db = piupartslib.packagesdb.PackagesDB(FakeLogDB())
db.read_packages_file(StringIO.StringIO(packages_file_contents))
return db
def reserve(self, packages_file_contents):
db = self.new_db(packages_file_contents)
return db.reserve_package()
def testNoPackages(self):
p = self.reserve("")
self.failUnlessEqual(p, None)
def testNoDeps(self):
p = self.reserve("""\
Package: foo
Version: 1.0-1
""")
self.failIfEqual(p, None)
self.failUnlessEqual(p["Package"], "foo")
if __name__ == "__main__":
unittest.main()
# vi:set et ts=4 sw=4 :
piuparts-0.64ubuntu1/tests/test_config.py 0000664 0000000 0000000 00000006575 12517712417 015572 0 ustar import unittest
import piupartslib.conf as conf
import distro_info
class ConfStdDistroTests(unittest.TestCase):
def setUp(self):
self.cobj = conf.Config('notimportant', {})
debdist = distro_info.DebianDistroInfo()
self.stable = debdist.stable()
self.unstable = debdist.devel()
self.oldstable = debdist.old()
self.testing = debdist.testing()
self.experimental = 'experimental'
def testConfStdDistroNames(self):
self.assertEqual(self.oldstable, 'wheezy')
self.assertEqual(self.stable, 'jessie')
self.assertEqual(self.testing, 'stretch')
self.assertEqual(self.unstable, 'sid')
self.assertEqual(self.experimental, 'experimental')
def testConfMapDistro(self):
self.assertEqual(self.cobj._map_distro('bogus'), 'unknown')
self.assertEqual(self.cobj._map_distro(self.oldstable), 'oldstable')
self.assertEqual(self.cobj._map_distro(self.stable), 'stable')
self.assertEqual(self.cobj._map_distro(self.testing), 'testing')
self.assertEqual(self.cobj._map_distro(self.unstable), 'unstable')
self.assertEqual(self.cobj._map_distro(self.experimental), 'experimental')
self.assertEqual(self.cobj._map_distro('oldstable'), 'oldstable')
self.assertEqual(self.cobj._map_distro('stable'), 'stable')
self.assertEqual(self.cobj._map_distro('testing'), 'testing')
self.assertEqual(self.cobj._map_distro('unstable'), 'unstable')
self.assertEqual(self.cobj._map_distro('experimental'), 'experimental')
def testConfMapProposedDistro(self):
self.assertEqual(
self.cobj._map_distro('stable-proposed'), 'stable')
self.assertEqual(
self.cobj._map_distro(self.stable + '-proposed'), 'stable')
def testConfMapRemainingDistros(self):
self.assertEqual(self.cobj._map_distro('rc-buggy'), 'experimental')
self.assertEqual(
self.cobj._map_distro('Debian6.0.9'),
self.cobj._map_distro('squeeze'))
self.assertEqual(
self.cobj._map_distro('Debian7.4'),
self.cobj._map_distro('wheezy'))
self.assertEqual(
self.cobj._map_distro('Debian8'),
self.cobj._map_distro('jessie'))
self.assertEqual(
self.cobj._map_distro('Debian8.1'),
self.cobj._map_distro('jessie'))
self.assertEqual(
self.cobj._map_distro('Debian9'),
self.cobj._map_distro('stretch'))
def testConfGetStdDistro(self):
for std in [
'oldstable', 'stable', 'testing', 'unstable', 'experimental']:
self.assertEqual(
self.cobj.get_std_distro([self.__dict__[std]]), std)
self.assertEqual(
self.cobj.get_std_distro([self.__dict__[std], 'unknown']), std)
self.assertEqual(
self.cobj.get_std_distro(['unknown', self.__dict__[std]]), std)
self.assertEqual(
self.cobj.get_std_distro(
['unknown', 'unknown', self.__dict__[std]]), std)
self.assertEqual(
self.cobj.get_std_distro(
[self.__dict__[std], 'unknown', 'unknown']), std)
self.assertEqual(self.cobj.get_std_distro(['unknown']), 'unknown')
self.assertEqual(
self.cobj.get_std_distro(['unknown', 'unknown']), 'unknown')
piuparts-0.64ubuntu1/tests/test_pkgsummary.py 0000664 0000000 0000000 00000012571 12517712417 016515 0 ustar import unittest
import datetime
import shutil
import tempfile
import os
import json
import piupartslib.pkgsummary as pkgsummary
class PkgSummaryTests(unittest.TestCase):
def testSummFlaginfoStateDups(self):
finfo = pkgsummary.flaginfo
states = sorted([y for x in finfo for y in finfo[x].states])
nodups = sorted(list(set(states)))
self.assertTrue('successfully-tested' in states)
self.assertEqual(states, nodups)
def testSummGetFlag(self):
self.assertEqual('F', pkgsummary.get_flag('failed-testing'))
self.assertEqual('X', pkgsummary.get_flag('dependency-does-not-exist'))
self.assertEqual('P', pkgsummary.get_flag('successfully-tested'))
self.assertEqual('W', pkgsummary.get_flag('waiting-to-be-tested'))
with self.assertRaises(pkgsummary.SummaryException):
pkgsummary.get_flag('bogus-state')
def testSummWorstFlag(self):
self.assertEqual('F', pkgsummary.worst_flag('F'))
self.assertEqual('P', pkgsummary.worst_flag('P'))
self.assertEqual('F', pkgsummary.worst_flag('P', 'F'))
self.assertEqual('F', pkgsummary.worst_flag('F', 'F'))
self.assertEqual('W', pkgsummary.worst_flag('W', 'P'))
self.assertEqual('F', pkgsummary.worst_flag('W', 'P', 'F', 'X', '-'))
with self.assertRaises(pkgsummary.SummaryException):
pkgsummary.worst_flag('Z')
class PkgSummaryAddTests(unittest.TestCase):
def setUp(self):
self.summ = pkgsummary.new_summary()
def testSummNewSumm(self):
# Verify any parameters which are depended on downstream
self.assertEqual("Piuparts Package Test Results Summary", self.summ['_id'])
self.assertEqual("1.0", self.summ['_version'])
self.assertEqual({}, self.summ['packages'])
thedate = datetime.datetime.strptime(self.summ['_date'], "%a %b %d %H:%M:%S UTC %Y")
def testSummAddArgValidation(self):
with self.assertRaises(pkgsummary.SummaryException):
pkgsummary.add_summary(
self.summ, 'foodist', 'foopkg', 'Z', 0, 'http://foo')
with self.assertRaises(pkgsummary.SummaryException):
pkgsummary.add_summary(
self.summ, 'foodist', 'foopkg', 'X', 'bogus',
'http://foo')
with self.assertRaises(pkgsummary.SummaryException):
pkgsummary.add_summary(
self.summ, 'foodist', 'foopkg', 'X', 1, 'ittp://foo')
pkgsummary.add_summary(
self.summ, 'foodist', 'foopkg', 'X', 1, 'http://foo')
def testSummAddArgStorageFormat(self):
# store non-overlapping entries
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'X', 0, 'http://foo')
pkgsummary.add_summary(
self.summ, 'dist', 'pkg2', 'W', 1, 'http://foo2')
pkgsummary.add_summary(
self.summ, 'dist2', 'pkg3', 'P', 2, 'http://foo3')
self.assertEqual(
['X', 0, 'http://foo'],
self.summ['packages']['pkg']['dist'])
self.assertEqual(
['W', 1, 'http://foo2'],
self.summ['packages']['pkg2']['dist'])
self.assertEqual(
['P', 2, 'http://foo3'],
self.summ['packages']['pkg3']['dist2'])
def testSummAddOverwriteFlag(self):
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'X', 0, 'http://foo')
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'P', 0, 'http://foo2')
self.assertEqual('X', self.summ['packages']['pkg']['dist'][0])
self.assertEqual('http://foo', self.summ['packages']['pkg']['dist'][2])
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'F', 0, 'http://foo3')
self.assertEqual('F', self.summ['packages']['pkg']['dist'][0])
self.assertEqual('http://foo3', self.summ['packages']['pkg']['dist'][2])
def testSummAddBlockCount(self):
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'X', 0, 'http://foo')
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'P', 1, 'http://foo')
self.assertEqual(1, self.summ['packages']['pkg']['dist'][1])
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'F', 2, 'http://foo')
self.assertEqual(2, self.summ['packages']['pkg']['dist'][1])
def testSummMerge(self):
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'X', 0, 'http://foo')
mergesumm = pkgsummary.new_summary()
pkgsummary.merge_summary(mergesumm, self.summ)
self.assertEqual(mergesumm['packages']['pkg']['dist'],
self.summ['packages']['pkg']['dist'])
self.assertEqual(mergesumm['packages']['pkg']['dist'],
mergesumm['packages']['pkg']['overall'])
class PkgSummaryStorageTests(unittest.TestCase):
def setUp(self):
self.summ = pkgsummary.new_summary()
pkgsummary.add_summary(self.summ, 'dist', 'pkg', 'X', 0, 'http://foo')
self.tmpdir = tempfile.mkdtemp()
self.tmpfilename = os.path.join(self.tmpdir, "foo.json")
pkgsummary.write_summary(self.summ, self.tmpfilename)
def tearDown(self):
shutil.rmtree(self.tmpdir)
def testSummFileRead(self):
summ2 = pkgsummary.read_summary(self.tmpfilename)
self.assertEqual(self.summ, summ2)
def testSummFileStorage(self):
with open(self.tmpfilename, 'r') as fl:
summ2 = json.load(fl)
self.assertEqual(self.summ, summ2)
piuparts-0.64ubuntu1/tests/test_piuparts.py 0000664 0000000 0000000 00000017776 12536542721 016201 0 ustar import unittest
from mox3 import mox
import os
import shutil
import piuparts
from piuparts import is_broken_symlink
class DefaultsFactoryTests(unittest.TestCase):
def setUp(self):
self.mox = mox.Mox()
self.df = piuparts.DefaultsFactory()
piuparts.settings = piuparts.Settings()
def tearDown(self):
self.mox.UnsetStubs()
def test_new_defaults_return_debian_defaults(self):
# mock the guess_flavor function as it runs lsb_release in a subprocess
self.mox.StubOutWithMock(self.df, 'guess_flavor')
self.df.guess_flavor().AndReturn('debian')
self.mox.ReplayAll()
defaults = self.df.new_defaults()
self.mox.VerifyAll()
self.assertEqual(defaults.get_keyring(), '/usr/share/keyrings/debian-archive-keyring.gpg')
self.assertEqual(defaults.get_components(), ["main", "contrib", "non-free"])
self.assertEqual(defaults.get_mirror(), [("http://httpredir.debian.org/debian", ["main", "contrib", "non-free"])])
self.assertEqual(defaults.get_distribution(), ['sid'])
def test_new_defaults_return_ubuntu_defaults(self):
# mock the guess_flavor function as it runs lsb_release in a subprocess
self.mox.StubOutWithMock(self.df, 'guess_flavor')
self.df.guess_flavor().AndReturn('ubuntu')
self.mox.ReplayAll()
defaults = self.df.new_defaults()
self.mox.VerifyAll()
self.assertEqual(defaults.get_keyring(), '/usr/share/keyrings/ubuntu-archive-keyring.gpg')
self.assertEqual(defaults.get_components(), ["main", "universe", "restricted", "multiverse"])
self.assertEqual(defaults.get_mirror(), [("http://archive.ubuntu.com/ubuntu", ["main", "universe", "restricted", "multiverse"])])
def test_new_defaults_panics_with_unknown_flavor(self):
# mock the guess_flavor function as it runs lsb_release in a subprocess
# and the panic function as it would use sys.exit()
self.mox.StubOutWithMock(self.df, 'guess_flavor')
self.df.guess_flavor().AndReturn('centos')
self.mox.StubOutWithMock(piuparts, 'panic')
piuparts.panic().AndReturn('Oh dear! Its CentOS!')
self.mox.ReplayAll()
defaults = self.df.new_defaults()
self.mox.VerifyAll()
# panic() would cause sys.exit() so no Defaults object would
# ever be returned
self.assertEqual(defaults, None)
class IsBrokenSymlinkTests(unittest.TestCase):
testdir = "is-broken-symlink-testdir"
def symlink(self, target, name):
pathname = os.path.join(self.testdir, name)
os.symlink(target, pathname)
self.symlinks.append(pathname)
def setUp(self):
self.symlinks = []
os.mkdir(self.testdir)
self.symlink("notexist", "relative-broken")
self.symlink("relative-broken", "relative-broken-to-symlink")
self.symlink(".", "relative-works")
self.symlink("relative-works", "relative-works-to-symlink")
self.symlink("/etc", "absolute-broken")
self.symlink("absolute-broken", "absolute-broken-to-symlink")
self.symlink("/", "absolute-works")
self.symlink("/absolute-works", "absolute-works-to-symlink")
os.mkdir(os.path.join(self.testdir, "dir"))
self.symlink("dir", "dir-link")
os.mkdir(os.path.join(self.testdir, "dir/subdir"))
self.symlink("subdir", "dir/subdir-link")
self.symlink("notexist/", "trailing-slash-broken")
self.symlink("dir/", "trailing-slash-works")
self.symlink("selfloop", "selfloop")
self.symlink("/absolute-selfloop", "absolute-selfloop")
self.symlink("../dir/selfloop", "dir/selfloop")
self.symlink("../dir-link/selfloop", "dir/selfloop1")
self.symlink("../../dir/subdir/selfloop", "dir/subdir/selfloop")
self.symlink("../../dir-link/subdir/selfloop", "dir/subdir/selfloop1")
self.symlink("../../link/subdir-link/selfloop", "dir/subdir/selfloop2")
self.symlink("../../dir-link/subdir-link/selfloop", "dir/subdir/selfloop3")
self.symlink("explode/bomb", "explode")
def tearDown(self):
shutil.rmtree(self.testdir)
def testRelativeBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"relative-broken"))
def testRelativeBrokenToSymlink(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"relative-broken-to-symlink"))
def testAbsoluteBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"absolute-broken"))
def testAbsoluteBrokenToSymlink(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"absolute-broken-to-symlink"))
def testTrailingSlashBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"trailing-slash-broken"))
def testSelfLoopBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"selfloop"))
def testExpandingSelfLoopBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"explode"))
def testAbsoluteSelfLoopBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"absolute-selfloop"))
def testSubdirSelfLoopBroken(self):
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/selfloop"))
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/selfloop1"))
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/subdir/selfloop"))
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/subdir/selfloop1"))
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/subdir/selfloop2"))
self.failUnless(is_broken_symlink(self.testdir, self.testdir,
"dir/subdir/selfloop3"))
def testRelativeWorks(self):
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"relative-works"))
def testRelativeWorksToSymlink(self):
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"relative-works-to-symlink"))
def testAbsoluteWorks(self):
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"absolute-works"))
def testAbsoluteWorksToSymlink(self):
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"absolute-works-to-symlink"))
def testTrailingSlashWorks(self):
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"trailing-slash-works"))
def testMultiLevelNestedSymlinks(self):
# target/first-link -> ../target/second-link -> ../target
os.mkdir(os.path.join(self.testdir, "target"))
self.symlink("../target", "target/second-link")
self.symlink("../target/second-link", "target/first-link")
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"target/first-link"))
def testMultiLevelNestedAbsoluteSymlinks(self):
# first-link -> /second-link/final-target
# second-link -> /target-dir
os.mkdir(os.path.join(self.testdir, "final-dir"))
os.mkdir(os.path.join(self.testdir, "final-dir/final-target"))
self.symlink("/second-link/final-target", "first-link")
self.symlink("/final-dir", "second-link")
self.failIf(is_broken_symlink(self.testdir, self.testdir,
"first-link"))
piuparts-0.64ubuntu1/NEWS 0000664 0000000 0000000 00000014655 12514657214 012247 0 ustar NEWS file for piuparts
======================
piuparts is a tool for testing that .deb packages can be
installed, upgraded, and removed without trouble. See
the README file and the manual page for more
information. This file summarizes the major changes,
particularly user visible changes, for each release.
Detailed change information can be found in bzr commit
messages.
This file is _deprecated_ now, see debian/NEWS.Debian instead!
Version 0.20, September 22, 2006
--------------------------------
When running external commands, use subprocess.Popen so that
there is no need for tricky (and therefore buggy) quoting
of shell command line arguments.
Version 0.19, September 8, 2006
-------------------------------
When reporting a bad symlink, show the target.
Version 0.18, September 7, 2006
-------------------------------
New features
Piuparts now checks for symlinks whose target does not
exist.
Option parsing code has been rewritten, and --help now
works better.
The chroot is now minimized before used: all unnecessary
packages are purged.
/dev/MAKEDEV, /etc/nologin, /usr/doc/cpio,
/var/spool/cron added to default ignores.
A version number may now begin with a + character. There
was a package that did that and piuparts crashed.
Version 0.17
------------
Bug fixes
The configuration files of piuparts-master/slave are
now documented in the README.
The Python profiler is no longer used. It used to be,
but that was a leftover from development (also known
as failure to read diffs before committing).
When testing upgrades between distributions, piuparts
now makes sure that the packages being tested are upgraded,
even if it means removing an old version of a dependency.
New features
Piuparts now checks for processes running inside the
chroot after it has installed or purged a package.
Because it uses policy-rc.d to prevent any services
from starting, no processes should run inside the
chroot after an installation or a purge has completed.
This check then finds packages that don't use invoke-rc.d
to start new processes.
A number of new default ignores have been added:
/etc/modprobe.d, compiled versions of debconf's Python
modules, papercut, ssl certificates.
/proc is now mounted (and unmounted) inside the chroot.
Version 0.16
------------
Bug fixes
The temporary directory for the chroot was not being
removed in all cases when running apt-get failed. This
has now been fixed.
New features
Added piuparts-analyze.py, which looks at new logs of
failed tests and compares them to logs of failed tests
for earlier versions of the same packages, and if so,
moves them automatically around. This saves a bit of
manual works. Thanks to Goswin Brederlow for the idea.
When piuparts creates a chroot from a tarball (option
-b), it now upgrades it before using it.
A number of new entries to the default ignores list.
Log files are now created with permissions that are
0666 modified with the process umask.
piuparts-report.py has been optimized somewhat.
Version 0.15
------------
Bug fixes
The dependency parser in piupartslib now understands
< and > (they're deprecated but one or two packges still
use them). It also now allows underscores in package
names because of the type-handling package.
Small fixes to the manual page.
New features and significant user visible changes
piuparts-master now understands Provides: headers.
A number of new entries to the default ignores list.
New option --keep-sources-list from John Wright.
Version 0.14
------------
Bug fixes
Specifications for ignoring some directories were buggy
and have now been fixed: /var/spool/news, /var/lib/cvs.
When testing a .deb file given on the command line,
if any of its dependencies were missing, the package
itself would be removed instead of piuparts reporting
an error. This has been fixed.
The check for whether a package is marked untestable
for piuparts-master now works.
New features and significant user visible changes
New program piuparts-report.py produces some "statistics"
about packages and their status with regard to testing
with piuparts-slave.
The chroot is always set up for piuparts, even if it is
unpacked from a tarball. This reduces problems with
out-of-date chroots and with using the pbuilder base.tgz
tarball.
Now ignored by default: /var/lib/firebird, /var/spool/news,
/var/lib/rbldns, /home/ftp.
Version 0.13
------------
Bug fixes
The configuration for apt-get (in the chroot) to allow
un-authenticated sources now actually works. There used
to be a typo.
New features and other user visible changes
The old run-piuparts.py script has been replaced by a
distributed system, consisting of piuparts-master.py and
piuparts-slave.py, plus a reporting script
piuparts-report.py. Since these are not useful for most
users, they're not installed on $PATH, but in
/usr/share/piuparts instead.
The slave part also runs upgrade tests between Debian
releases, which run-piuparts.py didn't.
Some additional files are ignored by default when
comparing the state of the chroot before and after
package installation.
piuparts-0.64ubuntu1/piuparts.py 0000664 0000000 0000000 00000361613 12604570246 013767 0 ustar #!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2005 Lars Wirzenius (liw@iki.fi)
# Copyright © 2010-2014 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""Debian package installation and uninstallation tester.
This program sets up a minimal Debian system in a chroot, and installs
and uninstalls packages and their dependencies therein, looking for
problems.
See the manual page (piuparts.1, generated from piuparts.1.txt) for
more usage information.
Lars Wirzenius
"""
VERSION = "__PIUPARTS_VERSION__"
import distro_info
import time
import logging
import optparse
import sys
import commands
import tempfile
import shutil
import os
import tarfile
import stat
import re
import pickle
import subprocess
import urllib
import uuid
from signal import alarm, signal, SIGALRM, SIGTERM, SIGKILL
try:
from debian import deb822
except ImportError:
from debian_bundle import deb822
import piupartslib.conf
DISTRO_CONFIG_FILE = "/etc/piuparts/distros.conf"
class Defaults:
"""Default settings which depend on flavor of Debian.
Some settings, such as the default mirror and distribution, depend on
which flavor of Debian we run under: Debian itself, or a derived
distribution such as Ubuntu. This class abstracts away the defaults
so that the rest of the code can just refer to the values defined
herein.
"""
def get_components(self):
"""Return list of default components for a mirror."""
def get_mirror(self):
"""Return default mirror."""
def get_distribution(self):
"""Return default distribution."""
def get_keyring(self):
"""Return default keyring."""
class DebianDefaults(Defaults):
def get_components(self):
return ["main", "contrib", "non-free"]
def get_mirror(self):
return [("http://httpredir.debian.org/debian", self.get_components())]
def get_distribution(self):
return [distro_info.DebianDistroInfo().devel()]
def get_keyring(self):
return "/usr/share/keyrings/debian-archive-keyring.gpg"
class UbuntuDefaults(Defaults):
def get_components(self):
return ["main", "universe", "restricted", "multiverse"]
def get_mirror(self):
return [("http://archive.ubuntu.com/ubuntu", self.get_components())]
def get_distribution(self):
return [distro_info.UbuntuDistroInfo().devel()]
def get_keyring(self):
return "/usr/share/keyrings/ubuntu-archive-keyring.gpg"
class DefaultsFactory:
"""Instantiate the right defaults class."""
def guess_flavor(self):
p = subprocess.Popen(["lsb_release", "-i", "-s"],
stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
return stdout.strip().lower()
def new_defaults(self):
if not settings.defaults:
settings.defaults = self.guess_flavor()
if settings.defaults.lower() == "debian":
return DebianDefaults()
if settings.defaults.lower() == "ubuntu":
return UbuntuDefaults()
logging.error("Unknown set of defaults: %s" % settings.defaults)
panic()
class Settings:
"""Global settings for this program."""
def __init__(self):
self.defaults = None
self.tmpdir = None
self.keep_tmpdir = False
self.max_command_output_size = 3 * 1024 * 1024 # 3 MB (daptup on dist-upgrade)
self.max_command_runtime = 30 * 60 # 30 minutes (texlive-full on dist-upgrade)
self.single_changes_list = False
self.args_are_package_files = True
# distro setup
self.proxy = None
self.debian_mirrors = []
self.extra_repos = []
self.testdebs_repo = None
self.debian_distros = []
self.keep_sources_list = False
self.keyring = None
self.do_not_verify_signatures = False
self.install_recommends = False
self.eatmydata = True
self.dpkg_force_unsafe_io = True
self.dpkg_force_confdef = False
self.scriptsdirs = []
self.bindmounts = []
self.allow_database = False
# chroot setup
self.arch = None
self.basetgz = None
self.savetgz = None
self.lvm_volume = None
self.lvm_snapshot_size = "1G"
self.adt_virt = None
self.existing_chroot = None
self.schroot = None
self.end_meta = None
self.save_end_meta = None
self.skip_minimize = True
self.minimize = False
self.debfoster_options = None
# tests and checks
self.no_install_purge_test = False
self.no_upgrade_test = False
self.distupgrade_to_testdebs = False
self.install_remove_install = False
self.install_purge_install = False
self.list_installed_files = False
self.extra_old_packages = []
self.skip_cronfiles_test = False
self.skip_logrotatefiles_test = False
self.adequate = True
self.check_broken_diversions = True
self.check_broken_symlinks = True
self.warn_broken_symlinks = True
self.warn_on_others = False
self.warn_on_leftovers_after_purge = False
self.warn_on_debsums_errors = False
self.warn_if_inadequate = True
self.pedantic_purge_test = False
self.ignored_files = [
# piuparts state
"/usr/sbin/policy-rc.d",
# system state
"/boot/grub/",
"/etc/X11/",
"/etc/X11/default-display-manager",
"/etc/aliases",
"/etc/aliases.db",
"/etc/crypttab",
"/etc/group",
"/etc/group-",
"/etc/group.org",
"/etc/gshadow",
"/etc/gshadow-",
"/etc/hosts",
"/etc/inetd.conf",
"/etc/inittab",
"/etc/ld.so.cache",
"/etc/machine-id",
"/etc/mailname",
"/etc/mtab",
"/etc/network/interfaces",
"/etc/news/",
"/etc/news/organization",
"/etc/news/server",
"/etc/news/servers",
"/etc/news/whoami",
"/etc/nologin",
"/etc/passwd",
"/etc/passwd-",
"/etc/passwd.org",
"/etc/shadow",
"/etc/shadow-",
"/etc/shadow.org",
"/etc/subgid",
"/etc/subgid-",
"/etc/subuid",
"/etc/subuid-",
"/usr/share/info/dir",
"/usr/share/info/dir.old",
"/var/cache/ldconfig/aux-cache",
"/var/crash/",
"/var/games/",
# package management
"/etc/apt/apt.conf.d/01autoremove-kernels",
"/etc/apt/secring.gpg",
"/etc/apt/trustdb.gpg",
"/etc/apt/trusted.gpg",
"/etc/apt/trusted.gpg~",
"/usr/share/keyrings/debian-archive-removed-keys.gpg~",
"/var/cache/apt/archives/lock",
"/var/cache/apt/archives/partial/",
"/var/cache/apt/pkgcache.bin",
"/var/cache/apt/srcpkgcache.bin",
"/var/cache/debconf/",
"/var/cache/debconf/config.dat",
"/var/cache/debconf/config.dat.old",
"/var/cache/debconf/config.dat-old",
"/var/cache/debconf/passwords.dat",
"/var/cache/debconf/passwords.dat.old",
"/var/cache/debconf/templates.dat",
"/var/cache/debconf/templates.dat.old",
"/var/cache/debconf/templates.dat-old",
"/var/lib/apt/extended_states",
"/var/lib/cdebconf/",
"/var/lib/cdebconf/passwords.dat",
"/var/lib/cdebconf/questions.dat",
"/var/lib/cdebconf/questions.dat-old",
"/var/lib/cdebconf/templates.dat",
"/var/lib/cdebconf/templates.dat-old",
"/var/lib/dpkg/arch",
"/var/lib/dpkg/available",
"/var/lib/dpkg/available-old",
"/var/lib/dpkg/diversions",
"/var/lib/dpkg/diversions-old",
"/var/lib/dpkg/lock",
"/var/lib/dpkg/status",
"/var/lib/dpkg/status-old",
"/var/lib/dpkg/statoverride",
"/var/lib/dpkg/statoverride-old",
"/var/log/alternatives.log",
"/var/log/apt/history.log",
"/var/log/apt/term.log",
"/var/log/bootstrap.log",
"/var/log/dbconfig-common/dbc.log",
"/var/log/dpkg.log",
# system logfiles
"/var/log/auth.log",
"/var/log/daemon.log",
"/var/log/debug",
"/var/log/faillog",
"/var/log/kern.log",
"/var/log/lastlog",
"/var/log/lpr.log",
"/var/log/mail.err",
"/var/log/mail.info",
"/var/log/mail.log",
"/var/log/mail.warn",
"/var/log/messages",
"/var/log/news/",
"/var/log/news/news.crit",
"/var/log/news/news.err",
"/var/log/news/news.notice",
"/var/log/secure",
"/var/log/syslog",
"/var/log/user.log",
# application logfiles
# actually, only modification should be permitted here, but not creation/removal
"/var/log/fontconfig.log",
# home directories of system accounts
"/var/lib/gozerbot/",
"/var/lib/nagios/", # nagios* (#668756)
"/var/lib/onioncat/", # onioncat
"/var/lib/rbldns/",
"/var/spool/powerdns/", # pdns-server (#531134), pdns-recursor (#531135)
# work around broken symlinks
"/usr/lib/python2.6/dist-packages/python-support.pth", # 635493 and #385775
"/usr/lib/python2.7/dist-packages/python-support.pth",
"/etc/modules-load.d/modules.conf",
# work around #316521 dpkg: incomplete cleanup of empty directories
"/etc/apache2/",
"/etc/apache2/conf.d/",
"/etc/clamav/",
"/etc/cron.d/",
"/etc/lighttpd/",
"/etc/lighttpd/conf-available/",
"/etc/nagios-plugins/config/",
"/etc/php5/",
"/etc/php5/conf.d/",
"/etc/php5/mods-available/",
"/etc/sgml/",
"/etc/ssl/",
"/etc/ssl/certs/",
"/etc/ssl/private/",
"/etc/xml/",
"/usr/share/dh-python/",
"/usr/share/dh-python/dhpython/",
"/usr/share/dh-python/dhpython/build/",
"/usr/share/python3/",
"/usr/share/python3/debpython/",
# HACKS
]
self.ignored_patterns = [
# system state
"/dev/.*",
"/etc/init.d/\.depend.*",
"/run/.*",
"/var/backups/.*",
"/var/cache/man/.*",
"/var/mail/.*",
"/var/run/.*",
# package management
"/etc/apt/trusted.gpg.d/.*.gpg~",
"/var/lib/apt/lists/.*",
"/var/lib/dpkg/alternatives/.*",
"/var/lib/dpkg/triggers/.*",
"/var/lib/insserv/run.*.log",
"/var/lib/ucf/.*",
"/var/lib/update-rc.d/.*",
# application data
"/var/lib/citadel/(data/.*)?",
"/var/lib/mercurial-server/.*",
"/var/lib/onak/.*",
"/var/lib/openvswitch/(pki/.*)?",
"/var/lib/vmm/(./.*)?", # 682184
"/var/log/exim/.*",
"/var/log/exim4/.*",
"/var/spool/exim/.*",
"/var/spool/exim4/.*",
"/var/spool/news/.*",
"/var/spool/squid/(../.*)?",
"/var/www/.*",
# HACKS
"/lib/modules/.*/modules.*",
]
self.non_pedantic_ignore_patterns = [
"/tmp/.*"
]
settings = Settings()
on_panic_hooks = {}
counter = 0
def do_on_panic(hook):
global counter
cid = counter
counter += 1
on_panic_hooks[cid] = hook
return cid
def dont_do_on_panic(id):
del on_panic_hooks[id]
class TimeOffsetFormatter(logging.Formatter):
def __init__(self, fmt=None, datefmt=None):
self.startup_time = time.time()
logging.Formatter.__init__(self, fmt, datefmt)
def formatTime(self, record, datefmt):
t = time.time() - self.startup_time
t_min = int(t / 60)
t_sec = t % 60.0
return "%dm%.1fs" % (t_min, t_sec)
DUMP = logging.DEBUG - 1
HANDLERS = []
def setup_logging(log_level, log_file_name):
logging.addLevelName(DUMP, "DUMP")
logger = logging.getLogger()
logger.setLevel(log_level)
formatter = TimeOffsetFormatter("%(asctime)s %(levelname)s: %(message)s")
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)
HANDLERS.append(handler)
if log_file_name:
handler = logging.FileHandler(log_file_name)
handler.setFormatter(formatter)
logger.addHandler(handler)
HANDLERS.append(handler)
def dump(msg):
logger = logging.getLogger()
logger.log(DUMP, msg)
for handler in HANDLERS:
handler.flush()
def panic(exit=1):
for i in range(counter):
if i in on_panic_hooks:
on_panic_hooks[i]()
logging.error("piuparts run ends.")
sys.exit(exit)
def indent_string(str):
"""Indent all lines in a string with two spaces and return result."""
return "\n".join([" " + line for line in str.split("\n")])
def quote_spaces(vlist):
return ["'%s'" % x if ' ' in x else x for x in vlist]
def unqualify(packages):
if packages:
return [p.split("=", 1)[0].strip() for p in packages]
return packages
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
def run(command, ignore_errors=False, timeout=0):
"""Run an external command and die with error message if it fails."""
def kill_subprocess(p, reason):
logging.error("Terminating command due to %s" % reason)
p.terminate()
for i in range(10):
time.sleep(0.5)
if p.poll() is not None:
break
else:
logging.error("Killing command due to %s" % reason)
p.kill()
p.wait()
assert isinstance(command, type([]))
logging.debug("Starting command: %s" % command)
env = os.environ.copy()
env["LC_ALL"] = "C"
env["LANGUAGES"] = ""
env["PIUPARTS_OBJECTS"] = ' '.join(str(vobject) for vobject in settings.testobjects)
devnull = open('/dev/null', 'r')
p = subprocess.Popen(command, env=env, stdin=devnull,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = ""
excessive_output = False
if timeout > 0:
signal(SIGALRM, alarm_handler)
alarm(timeout)
try:
while p.poll() is None:
"""Read 64 KB chunks, but depending on the output buffering behavior
of the command we may get less even if more output is coming later.
Abort after reading max_command_output_size bytes."""
output += p.stdout.read(1 << 16)
if (len(output) > settings.max_command_output_size):
excessive_output = True
ignore_errors = False
alarm(0)
kill_subprocess(p, "excessive output")
output += "\n\n***** Command was terminated after exceeding output limit (%.2f MB) *****\n" \
% (settings.max_command_output_size / 1024. / 1024.)
break
if not excessive_output:
output += p.stdout.read(settings.max_command_output_size)
alarm(0)
except Alarm:
ignore_errors = False
kill_subprocess(p, "excessive runtime")
output += "\n\n***** Command was terminated after exceeding runtime limit (%s s) *****\n" % timeout
devnull.close()
if output:
dump("\n" + indent_string(output.rstrip("\n")))
if p.returncode == 0:
logging.debug("Command ok: %s" % repr(command))
elif ignore_errors:
logging.debug("Command failed (status=%d), but ignoring error: %s" %
(p.returncode, repr(command)))
else:
logging.error("Command failed (status=%d): %s\n%s" %
(p.returncode, repr(command), indent_string(output)))
panic()
return p.returncode, output
def create_temp_file():
"""Create a temporary file and return its full path."""
(fd, path) = tempfile.mkstemp(dir=settings.tmpdir)
logging.debug("Created temporary file %s" % path)
return (fd, path)
def create_file(name, contents):
"""Create a new file with the desired name and contents."""
try:
f = file(name, "w")
f.write(contents)
f.close()
except IOError as detail:
logging.error("Couldn't create file %s: %s" % (name, detail))
panic()
def remove_files(filenames):
"""Remove some files."""
for filename in filenames:
logging.debug("Removing %s" % filename)
try:
os.remove(filename)
except OSError as detail:
logging.error("Couldn't remove %s: %s" % (filename, detail))
panic()
def make_metapackage(name, depends, conflicts):
"""Return the path to a .deb created just for satisfying dependencies
Caller is responsible for removing the temporary directory containing the
.deb when finished.
"""
# Inspired by pbuilder's pbuilder-satisfydepends-aptitude
tmpdir = tempfile.mkdtemp(dir=settings.tmpdir)
panic_handler_id = do_on_panic(lambda: shutil.rmtree(tmpdir))
create_file(os.path.join(tmpdir, ".piuparts.tmpdir"), "metapackage creation")
old_umask = os.umask(0)
os.makedirs(os.path.join(tmpdir, name, 'DEBIAN'), mode=0o755)
os.umask(old_umask)
control = deb822.Deb822()
control['Package'] = name
control['Version'] = '0.invalid.0'
control['Architecture'] = 'all'
control['Maintainer'] = ('piuparts developers team '
'')
control['Description'] = ('Dummy package to satisfy dependencies - '
'created by piuparts\n'
' This package was created automatically by '
'piuparts and can safely be removed')
if depends:
control['Depends'] = depends
if conflicts:
control['Conflicts'] = conflicts
create_file(os.path.join(tmpdir, name, 'DEBIAN', 'control'),
control.dump())
logging.debug("metapackage:\n" + indent_string(control.dump()))
run(['dpkg-deb', '-b', '-Zgzip', '--nocheck', os.path.join(tmpdir, name)])
dont_do_on_panic(panic_handler_id)
return os.path.join(tmpdir, name + '.deb')
def split_path(pathname):
parts = []
while pathname:
(head, tail) = os.path.split(pathname)
# print "split '%s' => '%s' + '%s'" % (pathname, head, tail)
if tail:
parts.append(tail)
elif not head:
break
elif head == pathname:
parts.append(head)
break
pathname = head
return parts
def canonicalize_path(root, pathname, report_links=False):
"""Canonicalize a path name, simulating chroot at 'root'.
When resolving the symlink, pretend (similar to chroot) that
'root' is the root of the filesystem. Also resolve '..' and
'.' components. This should not escape the chroot below
'root', but for security concerns, use chroot and have the
kernel resolve symlinks instead.
Returns the final canonical path or a list of (path, target) tuples,
one for each symlink encountered.
"""
# print "\nCANONICALIZE %s %s" % (root, pathname)
links = []
seen = []
parts = split_path(pathname)
# print "PARTS ", list(reversed(parts))
path = "/"
while parts:
tag = "\n".join(parts + [path])
# print "TEST '%s' + " % path, list(reversed(parts))
if tag in seen or len(seen) > 1024:
fullpath = os.path.join(path, *reversed(parts))
# print "LOOP %s" % fullpath
path = fullpath
logging.error("ELOOP: Too many symbolic links in '%s'" % path)
break
seen.append(tag)
part = parts.pop()
# Using normpath() to cleanup '.', '..' and multiple slashes.
# Removing a suffix 'foo/..' is safe here since it can't change the
# meaning of 'path' because it contains no symlinks - they have been
# resolved already.
newpath = os.path.normpath(os.path.join(path, part))
rootedpath = os.path.join(root, newpath[1:])
if newpath == "/":
path = "/"
elif os.path.islink(rootedpath):
target = os.readlink(rootedpath)
# print "LINK to '%s'" % target
links.append((newpath, target))
if os.path.isabs(target):
path = "/"
parts.extend(split_path(target))
else:
path = newpath
# print "FINAL '%s'" % path
if report_links:
return links
return path
def is_broken_symlink(root, dirpath, filename):
"""Is symlink dirpath+filename broken?"""
if dirpath[:len(root)] == root:
dirpath = dirpath[len(root):]
pathname = canonicalize_path(root, os.path.join(dirpath, filename))
pathname = os.path.join(root, pathname[1:])
# The symlink chain, if any, has now been resolved. Does the target
# exist?
# print "EXISTS ", pathname, os.path.exists(pathname)
return not os.path.exists(pathname)
class Chroot:
"""A chroot for testing things in."""
def __init__(self):
self.name = None
self.bootstrapped = False
def create_temp_dir(self):
"""Create a temporary directory for the chroot."""
self.name = tempfile.mkdtemp(dir=settings.tmpdir)
create_file(os.path.join(self.name, ".piuparts.tmpdir"), "chroot")
os.chmod(self.name, 0o755)
logging.debug("Created temporary directory %s" % self.name)
def create(self, temp_tgz=None):
"""Create a chroot according to user's wishes."""
self.panic_handler_id = do_on_panic(self.remove)
if not settings.schroot:
self.create_temp_dir()
if temp_tgz:
self.unpack_from_tgz(temp_tgz)
elif settings.basetgz:
self.unpack_from_tgz(settings.basetgz)
elif settings.lvm_volume:
self.setup_from_lvm(settings.lvm_volume)
elif settings.existing_chroot:
self.setup_from_dir(settings.existing_chroot)
elif settings.schroot:
self.setup_from_schroot(settings.schroot)
else:
self.setup_minimal_chroot()
if not settings.schroot:
self.mount_proc()
self.mount_selinux()
self.configure_chroot()
# Copy scripts dirs into the chroot, merging all dirs together,
# later files overwriting earlier ones.
if settings.scriptsdirs:
dest = self.relative("tmp/scripts/")
if not os.path.exists(self.relative("tmp/scripts/")):
os.mkdir(dest)
for sdir in settings.scriptsdirs:
logging.debug("Copying scriptsdir %s to %s" % (sdir, dest))
for sfile in os.listdir(sdir):
if (sfile.startswith("post_") or sfile.startswith("pre_")) \
and not ".dpkg-" in sfile \
and os.path.isfile(os.path.join(sdir, sfile)):
shutil.copy(os.path.join(sdir, sfile), dest)
# Run custom scripts after chroot has been unpacked/debootstrapped
# Useful for adjusting apt configuration e.g. for internal mirror usage
self.run_scripts("post_chroot_unpack")
if settings.basetgz or settings.schroot:
self.run(["apt-get", "-yf", "dist-upgrade"])
self.minimize()
# Run custom scripts after creating the chroot.
self.run_scripts("post_setup")
if settings.savetgz and not temp_tgz:
self.pack_into_tgz(settings.savetgz)
def remove(self):
"""Remove a chroot and all its contents."""
if not settings.keep_tmpdir and os.path.exists(self.name):
self.terminate_running_processes()
if not settings.schroot:
self.unmount_selinux()
self.unmount_proc()
if settings.lvm_volume:
logging.debug('Unmounting and removing LVM snapshot %s' % self.lvm_snapshot_name)
run(['umount', self.name])
run(['lvremove', '-f', self.lvm_snapshot])
if settings.schroot:
logging.debug("Terminate schroot session '%s'" % self.name)
run(['schroot', '--end-session', '--chroot', "session:" + self.schroot_session])
if not settings.schroot:
run(['rm', '-rf', '--one-file-system', self.name])
if os.path.exists(self.name):
create_file(os.path.join(self.name, ".piuparts.tmpdir"), "removal failed")
logging.debug("Removed directory tree at %s" % self.name)
elif settings.keep_tmpdir:
if settings.schroot:
logging.debug("Keeping schroot session %s at %s" % (self.schroot_session, self.name))
else:
logging.debug("Keeping directory tree at %s" % self.name)
dont_do_on_panic(self.panic_handler_id)
def was_bootstrapped(self):
return self.bootstrapped
def create_temp_tgz_file(self):
"""Return the path to a file to be used as a temporary tgz file"""
# Yes, create_temp_file() would work just as well, but putting it in
# the interface for Chroot allows the VirtServ hack to work.
(fd, temp_tgz) = create_temp_file()
os.close(fd)
return temp_tgz
def remove_temp_tgz_file(self, temp_tgz):
"""Remove the file that was used as a temporary tgz file"""
# Yes, remove_files() would work just as well, but putting it in
# the interface for Chroot allows the VirtServ hack to work.
remove_files([temp_tgz])
def pack_into_tgz(self, result):
"""Tar and compress all files in the chroot."""
self.run(["apt-get", "clean"])
logging.debug("Saving %s to %s." % (self.name, result))
(fd, tmpfile) = tempfile.mkstemp(dir=os.path.dirname(result))
os.close(fd)
cleanup_tmpfile = lambda: os.remove(tmpfile)
panic_handler_id = do_on_panic(cleanup_tmpfile)
run(['tar', '-czf', tmpfile, '--one-file-system', '--exclude', 'tmp/scripts', '-C', self.name, './'])
os.chmod(tmpfile, 0o644)
os.rename(tmpfile, result)
dont_do_on_panic(panic_handler_id)
def unpack_from_tgz(self, tarball):
"""Unpack a tarball to a chroot."""
logging.debug("Unpacking %s into %s" % (tarball, self.name))
prefix = []
if settings.eatmydata and os.path.isfile('/usr/bin/eatmydata'):
prefix.append('eatmydata')
run(prefix + ["tar", "-C", self.name, "-zxf", tarball])
def setup_from_schroot(self, schroot):
self.schroot_session = schroot.split(":", 1)[-1] + "-" + str(uuid.uuid1()) + "-piuparts"
run(['schroot', '--begin-session', '--chroot', schroot, '--session-name', self.schroot_session])
ret_code, output = run(['schroot', '--chroot', "session:" + self.schroot_session, '--location'])
self.name = output.strip()
logging.info("New schroot session in '%s'" % self.name)
def setup_from_lvm(self, lvm_volume):
"""Create a chroot by creating an LVM snapshot."""
self.lvm_base = os.path.dirname(lvm_volume)
self.lvm_vol_name = os.path.basename(lvm_volume)
self.lvm_snapshot_name = self.lvm_vol_name + "-" + str(uuid.uuid1())
self.lvm_snapshot = os.path.join(self.lvm_base, self.lvm_snapshot_name)
logging.debug("Creating LVM snapshot %s from %s" % (self.lvm_snapshot, lvm_volume))
run(['lvcreate', '-n', self.lvm_snapshot, '-s', lvm_volume, '-L', settings.lvm_snapshot_size])
logging.info("Mounting LVM snapshot to %s" % self.name)
run(['mount', self.lvm_snapshot, self.name])
def setup_from_dir(self, dirname):
"""Create chroot from an existing one."""
# if on same device, make hard link
cmd = ["cp"]
if os.stat(dirname).st_dev == os.stat(self.name).st_dev:
cmd += ["-al"]
logging.debug("Hard linking %s to %s" % (dirname, self.name))
else:
cmd += ["-ax"]
logging.debug("Copying %s into %s" % (dirname, self.name))
for name in os.listdir(dirname):
src = os.path.join(dirname, name)
dst = os.path.join(self.name, name)
run(cmd + [src, dst])
def run(self, command, ignore_errors=False):
prefix = []
if settings.eatmydata and os.path.isfile(os.path.join(self.name,
'usr/bin/eatmydata')):
prefix.append('eatmydata')
if settings.schroot:
return run(
["schroot", "--preserve-environment", "--run-session", "--chroot", "session:" +
self.schroot_session, "--directory", "/", "-u", "root", "--"] + prefix + command,
ignore_errors=ignore_errors, timeout=settings.max_command_runtime)
else:
return run(["chroot", self.name] + prefix + command,
ignore_errors=ignore_errors, timeout=settings.max_command_runtime)
def mkdir_p(self, path):
fullpath = self.relative(path)
if not os.path.isdir(fullpath):
os.makedirs(fullpath)
def create_apt_sources(self, distro):
"""Create an /etc/apt/sources.list with a given distro."""
lines = []
lines.extend(settings.distro_config.get_deb_lines(
distro, settings.debian_mirrors[0][1]))
for mirror, components in settings.debian_mirrors[1:]:
lines.append("deb %s %s %s" %
(mirror, distro, " ".join(components)))
for repo in settings.extra_repos:
lines.append(repo)
create_file(self.relative("etc/apt/sources.list"),
"\n".join(lines) + "\n")
logging.debug("sources.list:\n" + indent_string("\n".join(lines)))
def enable_testdebs_repo(self, update=True):
if settings.testdebs_repo:
if settings.testdebs_repo.startswith("deb"):
debline = settings.testdebs_repo
elif settings.testdebs_repo.startswith("/"):
debline = "deb file://%s ./" % settings.testdebs_repo
else:
debline = "deb %s ./" % settings.testdebs_repo
logging.debug("enabling testdebs repository '%s'" % debline)
create_file(self.relative("etc/apt/sources.list.d/piuparts-testdebs-repo.list"), debline + "\n")
if update:
self.run(["apt-get", "update"])
def disable_testdebs_repo(self):
if settings.testdebs_repo:
logging.debug("disabling testdebs repository")
remove_files([self.relative("etc/apt/sources.list.d/piuparts-testdebs-repo.list")])
def create_apt_conf(self):
"""Create /etc/apt/apt.conf.d/piuparts inside the chroot."""
lines = ['APT::Get::Assume-Yes "yes";\n']
lines.append('APT::Install-Recommends "%d";\n' % int(settings.install_recommends))
lines.append('APT::Install-Suggests "0";\n')
lines.append('APT::Get::AllowUnauthenticated "%s";\n' % settings.apt_unauthenticated)
lines.append('Acquire::PDiffs "false";\n')
if settings.proxy:
proxy = settings.proxy
elif "http_proxy" in os.environ:
proxy = os.environ["http_proxy"]
else:
proxy = None
pat = re.compile(r"^Acquire::http::Proxy\s+\"([^\"]+)\"", re.I)
p = subprocess.Popen(["apt-config", "dump"],
stdout=subprocess.PIPE)
stdout, _ = p.communicate()
if stdout:
for line in stdout.split("\n"):
m = re.match(pat, line)
if proxy is None and m:
proxy = m.group(1)
if proxy:
lines.append('Acquire::http::Proxy "%s";\n' % proxy)
if settings.dpkg_force_unsafe_io:
lines.append('Dpkg::Options {"--force-unsafe-io";};\n')
if settings.dpkg_force_confdef:
lines.append('Dpkg::Options {"--force-confdef";};\n')
create_file(self.relative("etc/apt/apt.conf.d/piuparts"),
"".join(lines))
def create_dpkg_conf(self):
"""Create /etc/dpkg/dpkg.cfg.d/piuparts inside the chroot."""
lines = []
if settings.dpkg_force_unsafe_io:
lines.append('force-unsafe-io\n')
if settings.dpkg_force_confdef:
lines.append('force-confdef\n')
logging.info("Warning: dpkg has been configured to use the force-confdef option. This will hide problems, see #466118.")
if lines:
if not os.path.exists(self.relative("etc/dpkg/dpkg.cfg.d")):
os.mkdir(self.relative("etc/dpkg/dpkg.cfg.d"))
create_file(self.relative("etc/dpkg/dpkg.cfg.d/piuparts"),
"".join(lines))
def create_policy_rc_d(self):
"""Create a policy-rc.d that prevents daemons from running."""
full_name = self.relative("usr/sbin/policy-rc.d")
policy = "#!/bin/sh\n"
if settings.allow_database:
policy += 'test "$1" = "mysql" && exit 0\n'
policy += 'test "$1" = "postgresql" && exit 0\n'
policy += 'test "$1" = "postgresql-8.3" && exit 0\n'
policy += 'test "$1" = "firebird2.5-super" && exit 0\n'
policy += "exit 101\n"
create_file(full_name, policy)
os.chmod(full_name, 0o755)
logging.debug("Created policy-rc.d and chmodded it.")
def create_resolv_conf(self):
"""Update resolv.conf based on the current configuration in the host system. Strip comments and whitespace."""
full_name = self.relative("etc/resolv.conf")
resolvconf = ""
with open("/etc/resolv.conf", "r") as f:
for line in f:
if line.strip() and not line.startswith(('#', ';')):
resolvconf += line.strip() + '\n'
create_file(full_name, resolvconf)
logging.debug("Created resolv.conf.")
def setup_minimal_chroot(self):
"""Set up a minimal Debian system in a chroot."""
logging.debug("Setting up minimal chroot for %s at %s." %
(settings.debian_distros[0], self.name))
prefix = []
if settings.eatmydata and os.path.isfile('/usr/bin/eatmydata'):
prefix.append('eatmydata')
options = []
if settings.do_not_verify_signatures:
logging.info("Warning: not using --keyring option when running debootstrap!")
else:
options.append("--keyring=%s" % settings.keyring)
if settings.eatmydata:
options.append('--include=eatmydata')
options.append('--components=%s' % ','.join(settings.debian_mirrors[0][1]))
if settings.arch:
options.append('--arch=%s' % settings.arch)
run(prefix + ["debootstrap", "--variant=minbase"] + options +
[settings.debian_distros[0], self.name, settings.distro_config.get_mirror(settings.debian_distros[0])])
self.bootstrapped = True
def minimize(self):
"""Minimize a chroot by removing (almost all) unnecessary packages"""
if settings.skip_minimize or not settings.minimize:
return
self.run(["apt-get", "install", "debfoster"])
debfoster_command = ["debfoster"] + settings.debfoster_options
if settings.eatmydata:
debfoster_command.append("eatmydata")
self.run(debfoster_command)
remove_files([self.relative("var/lib/debfoster/keepers")])
self.run(["dpkg", "--purge", "debfoster"])
def configure_chroot(self):
"""Configure a chroot according to current settings"""
os.environ["PIUPARTS_DISTRIBUTION"] = settings.distro_config.get_distribution(settings.debian_distros[0])
if not settings.keep_sources_list:
self.create_apt_sources(settings.debian_distros[0])
self.create_apt_conf()
self.create_dpkg_conf()
self.create_policy_rc_d()
self.create_resolv_conf()
for bindmount in settings.bindmounts:
run(["mkdir", "-p", self.relative(bindmount)])
run(["mount", "-obind", bindmount, self.relative(bindmount)])
self.run(["apt-get", "update"])
def upgrade_to_distros(self, distros, packages):
"""Upgrade a chroot installation to each successive distro."""
for distro in distros:
logging.debug("Upgrading %s to %s" % (self.name, distro))
os.environ["PIUPARTS_DISTRIBUTION_NEXT"] = settings.distro_config.get_distribution(distro)
self.create_apt_sources(distro)
# Run custom scripts before upgrade
self.run_scripts("pre_distupgrade")
self.run(["apt-get", "update"])
self.run(["apt-get", "-yf", "dist-upgrade"])
os.environ["PIUPARTS_DISTRIBUTION_PREV"] = os.environ["PIUPARTS_DISTRIBUTION"]
os.environ["PIUPARTS_DISTRIBUTION"] = settings.distro_config.get_distribution(distro)
# Sometimes dist-upgrade won't upgrade the packages we want
# to test because the new version depends on a newer library,
# and installing that would require removing the old version
# of the library, and we've told apt-get not to remove
# packages. So, we force the installation like this.
if packages:
known_packages = self.get_known_packages(packages + settings.extra_old_packages)
self.install_packages_by_name(known_packages)
# Run custom scripts after upgrade
self.run_scripts("post_distupgrade")
self.check_for_no_processes()
def get_known_packages(self, packages):
"""Does apt-get (or apt-cache) know about a set of packages?"""
known_packages = []
new_packages = []
for name in packages:
(status, output) = self.run(["apt-cache", "show", name],
ignore_errors=True)
# apt-cache reports status for some virtual packages and packages
# in status config-files-remaining state without installation
# candidate -- but only real packages have Filename/MD5sum/SHA*
if status != 0 or re.search(r'^(Filename|MD5sum|SHA1|SHA256):', output, re.M) is None:
new_packages.append(name)
else:
known_packages.append(name)
if not known_packages:
logging.info("apt-cache does not know about any of the requested packages")
else:
logging.info("apt-cache knows about the following packages: " +
", ".join(known_packages))
if new_packages:
logging.info("the following packages are not in the archive: " +
", ".join(new_packages))
return known_packages
def copy_files(self, source_names, target_name):
"""Copy files in 'source_name' to file/dir 'target_name', relative
to the root of the chroot."""
target_name = self.relative(target_name)
logging.debug("Copying %s to %s" %
(", ".join(source_names), target_name))
for source_name in source_names:
try:
shutil.copy(source_name, target_name)
except IOError as detail:
logging.error("Error copying %s to %s: %s" %
(source_name, target_name, detail))
panic()
def list_installed_files(self, pre_info, post_info):
"""List the new files installed, removed and modified between two dir trees.
Actually, it is a nice output of the funcion diff_meta_dat."""
(new, removed, modified) = diff_meta_data(pre_info, post_info)
file_owners = self.get_files_owned_by_packages()
if new:
logging.debug("New installed files on system:\n" + file_list(new, file_owners))
else:
logging.debug("The package did not install any new file.\n")
if removed:
logging.debug("The following files have disappeared:\n" +
file_list(removed, file_owners))
if modified:
logging.debug("The following files have been modified:\n" +
file_list(modified, file_owners))
else:
logging.debug("The package did not modify any file.\n")
def is_installed(self, packages):
if not packages:
return True
retcode, output = self.run(["dpkg-query", "-f", "${Package} ${Status}\n", "-W"] + packages, ignore_errors=True)
if retcode != 0:
return False
installed = True
for line in output.splitlines():
pkg, desired, whatever, status = line.split()
if status != 'installed':
logging.error("Installation of %s failed", pkg)
installed = False
return installed
def install_packages(self, package_files, packages, with_scripts=True):
if package_files:
self.install_package_files(package_files, packages, with_scripts=with_scripts)
else:
self.install_packages_by_name(packages, with_scripts=with_scripts)
def install_package_files(self, package_files, packages=None, with_scripts=False):
if packages and settings.testdebs_repo:
self.install_packages_by_name(packages, with_scripts=with_scripts)
return
if package_files:
self.copy_files(package_files, "tmp")
tmp_files = [os.path.basename(a) for a in package_files]
tmp_files = [os.path.join("tmp", name) for name in tmp_files]
if with_scripts:
self.run_scripts("pre_install")
apt_get_install = ["apt-get", "-yf"]
apt_get_install.extend(settings.distro_config.get_target_flags(
os.environ["PIUPARTS_DISTRIBUTION"]))
apt_get_install.append("install")
if settings.list_installed_files:
pre_info = self.save_meta_data()
self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True)
self.list_installed_files(pre_info, self.save_meta_data())
self.run(apt_get_install)
self.list_installed_files(pre_info, self.save_meta_data())
else:
self.run(["dpkg", "-i"] + tmp_files, ignore_errors=True)
self.run(apt_get_install)
if not self.is_installed(unqualify(packages)):
logging.error("Could not install %s.", " ".join(unqualify(packages)))
panic()
logging.info("Installation of %s ok", tmp_files)
if with_scripts:
self.run_scripts("post_install")
remove_files([self.relative(name) for name in tmp_files])
def install_packages_by_name(self, packages, with_scripts=True):
if packages:
if with_scripts:
self.run_scripts("pre_install")
self.run(["apt-cache", "policy"])
self.run(["apt-cache", "policy"] + unqualify(packages))
if settings.list_installed_files:
pre_info = self.save_meta_data()
target_flags = settings.distro_config.get_target_flags(os.environ["PIUPARTS_DISTRIBUTION"])
self.apt_get_install(to_install=packages, flags=target_flags)
if settings.list_installed_files:
self.list_installed_files(pre_info, self.save_meta_data())
if with_scripts:
self.run_scripts("post_install")
def apt_get_install(self, to_install=[], to_remove=[], to_purge=[], flags=[]):
command = ["apt-get", "-y"] + flags + ["install"]
command.extend(to_install)
command.extend(["%s-" % x for x in unqualify(to_remove)])
command.extend(["%s_" % x for x in unqualify(to_purge)])
self.run(command)
def get_selections(self):
"""Get current package selections in a chroot."""
# "${Status}" emits three columns, e.g. "install ok installed"
# "${binary:Package}" requires a multi-arch dpkg, so fall back to "${Package}" on older versions
(status, output) = self.run(["dpkg-query", "-W", "-f", "${Status}\\t${binary:Package}\\t${Package}\\t${Version}\\n"])
vdict = {}
for line in [line for line in output.split("\n") if line.strip()]:
token = line.split()
status = token[0]
name = token[3]
if status == "install":
version = token[-1]
else:
version = None
vdict[name] = (status, version)
return vdict
def get_diversions(self):
"""Get current dpkg-divert --list in a chroot."""
if not settings.check_broken_diversions:
return
(status, output) = self.run(["dpkg-divert", "--list"])
return output.split("\n")
def get_modified_diversions(self, pre_install_diversions, post_install_diversions=None):
"""Check that diversions in chroot are identical (though potentially reordered)."""
if post_install_diversions is None:
post_install_diversions = self.get_diversions()
removed = [ln for ln in pre_install_diversions if not ln in post_install_diversions]
added = [ln for ln in post_install_diversions if not ln in pre_install_diversions]
return (removed, added)
def check_debsums(self):
(status, output) = run(["debsums", "--root", self.name, "-ac"], ignore_errors=True)
if status != 0:
logging.error("FAIL: debsums reports modifications inside the chroot:\n%s" %
indent_string(output.replace(self.name, "")))
if not settings.warn_on_debsums_errors:
panic()
def check_adequate(self, packages):
"""Run adequate and categorize output according to our needs. """
packages = unqualify([p for p in packages if not p.endswith("=None")])
if packages and settings.adequate and os.path.isfile('/usr/bin/adequate'):
(status, output) = run(["dpkg-query", "-f", "${Version}\n", "-W", "adequate"], ignore_errors=True)
logging.info("Running adequate version %s now." % output.strip())
adequate_tags = [
'bin-or-sbin-binary-requires-usr-lib-library',
'broken-binfmt-detector',
'broken-binfmt-interpreter',
'incompatible-licenses',
'ldd',
'library-not-found',
'missing-alternative',
'missing-copyright-file',
'missing-pkgconfig-dependency',
'missing-symbol-version-information',
'program-name-collision',
'py-file-not-bytecompiled',
'pyshared-file-not-bytecompiled',
'symbol-size-mismatch',
'undefined-symbol',
]
boring_tags = [
'obsolete-conffile',
'broken-symlink',
]
ignored_tags = []
(status, output) = run(["adequate", "--root", self.name] + packages, ignore_errors=True)
for tag in ignored_tags:
# ignore some tags
_regex = '^[^:]+: ' + tag + ' .*\n'
output = re.compile(_regex, re.MULTILINE).sub('', output)
if output:
inadequate_results = ''
boring_results = ''
for tag in adequate_tags:
if ' ' + tag + ' ' in output:
inadequate_results += ' ' + tag + ' '
for tag in boring_tags:
if ' ' + tag + ' ' in output:
boring_results += ' ' + tag + ' '
if settings.warn_if_inadequate:
error_code = 'WARN'
else:
error_code = 'FAIL'
logging.error("%s: Inadequate results from running adequate!\n%s" %
(error_code, indent_string(output.replace(self.name, ""))))
if inadequate_results:
logging.error("%s: Running adequate resulted in inadequate tags found: %s" % (error_code, inadequate_results))
if boring_results:
logging.error("%s: Running adequate resulted in less interesting tags found: %s" % (error_code, boring_results))
if not boring_results and not inadequate_results:
logging.error("%s: Found unknown tags running adequate." % error_code)
if status != 0:
logging.error("%s: Exit code from adequate was %s!" % (error_code, status))
if not settings.warn_if_inadequate:
panic()
def list_paths_with_symlinks(self):
file_owners = self.get_files_owned_by_packages()
bad = []
overwrites = False
for f in sorted(file_owners.keys()):
dn, fn = os.path.split(f)
dc = canonicalize_path(self.name, dn)
if dn != dc:
fc = os.path.join(dc, fn)
of = ", ".join(file_owners[f])
if fc in file_owners:
overwrites = True
ofc = ", ".join(file_owners[fc])
else:
ofc = "?"
bad.append("%s (%s) != %s (%s)" % (f, of, fc, ofc))
for (link, target) in canonicalize_path(self.name, dn, report_links=True):
bad.append(" %s -> %s" % (link, target))
if bad:
if overwrites:
logging.error("FAIL: silently overwrites files via directory symlinks:\n" +
indent_string("\n".join(bad)))
else:
logging.info("dirname part contains a symlink:\n" +
indent_string("\n".join(bad)))
def remove_packages(self, packages):
"""Remove packages in a chroot."""
if packages:
self.run(["apt-get", "remove"] + unqualify(packages), ignore_errors=True)
def purge_packages(self, packages):
"""Purge packages in a chroot."""
if packages:
self.run(["dpkg", "--purge"] + unqualify(packages), ignore_errors=True)
def restore_selections(self, selections, packages_qualified):
"""Restore package selections in a chroot to the state in
'selections'."""
packages = unqualify(packages_qualified)
changes = diff_selections(self, selections)
deps = {}
nondeps = {}
for name, state_version in changes.iteritems():
if name in packages:
nondeps[name] = state_version
else:
deps[name] = state_version
deps_to_remove = [name for name, (state, version) in deps.iteritems()
if state == "remove"]
deps_to_purge = [name for name, (state, version) in deps.iteritems()
if state == "purge"]
nondeps_to_remove = [name for name, (state, version) in nondeps.iteritems()
if state == "remove"]
nondeps_to_purge = [name for name, (state, version) in nondeps.iteritems()
if state == "purge"]
all_to_remove = deps_to_remove + deps_to_purge + nondeps_to_remove + nondeps_to_purge
all_to_install = [(name, version) for name, (state, version) in deps.iteritems()
if state == "install"]
all_to_install += [(name, version) for name, (state, version) in nondeps.iteritems()
if state == "install"]
self.list_paths_with_symlinks()
self.check_debsums()
self.check_adequate(packages_qualified)
# Run custom scripts before removing all packages.
self.run_scripts("pre_remove")
# First remove all packages (and reinstall missing ones).
self.remove_packages(deps_to_remove)
if all_to_install:
version_qualified = [name for (name, version) in all_to_install
if version is None]
version_qualified += ["%s=%s" % (name, version) for (name, version) in all_to_install
if version is not None]
self.apt_get_install(to_remove=all_to_remove,
to_install=version_qualified,
flags=["--no-install-recommends", "--force-yes"])
else:
self.remove_packages(all_to_remove)
# Run custom scripts after removing all packages.
self.run_scripts("post_remove")
if not settings.skip_cronfiles_test:
cronfiles, cronfiles_list = self.check_if_cronfiles(packages)
if not settings.skip_cronfiles_test and cronfiles:
self.check_output_cronfiles(cronfiles_list)
if not settings.skip_logrotatefiles_test:
logrotatefiles, logrotatefiles_list = self.check_if_logrotatefiles(packages)
if not settings.skip_logrotatefiles_test and logrotatefiles:
installed = self.install_logrotate()
self.check_output_logrotatefiles(logrotatefiles_list)
self.purge_packages(installed)
# Then purge all packages being depended on.
self.purge_packages(deps_to_purge)
# Finally, purge actual packages.
self.purge_packages(nondeps_to_purge)
# Run custom scripts after purge all packages.
self.run_scripts("post_purge")
# Now do a final run to see that everything worked.
self.run(["dpkg", "--purge", "--pending"])
self.run(["dpkg", "--remove", "--pending"])
def save_meta_data(self):
"""Return the filesystem meta data for all objects in the chroot."""
self.run(["apt-get", "clean"])
root = self.relative(".")
vdict = {}
proc = os.path.join(root, "proc")
devpts = os.path.join(root, "dev/pts")
for dirpath, dirnames, filenames in os.walk(root):
assert dirpath[:len(root)] == root
if dirpath[:len(proc) + 1] in [proc, proc + "/"]:
continue
if dirpath[:len(devpts) + 1] in [devpts, devpts + "/"]:
continue
for name in [dirpath] + \
[os.path.join(dirpath, f) for f in filenames]:
st = os.lstat(name)
if stat.S_ISLNK(st.st_mode):
target = os.readlink(name)
else:
target = None
if stat.S_ISDIR(st.st_mode):
name += "/"
vdict[name[len(root):]] = (st, target)
return vdict
def relative(self, pathname):
if pathname.startswith('/'):
return os.path.join(self.name, pathname[1:])
return os.path.join(self.name, pathname)
def get_files_owned_by_packages(self):
"""Return dict[filename] = [packagenamelist]."""
vdir = self.relative("var/lib/dpkg/info")
vdict = {}
for basename in os.listdir(vdir):
if basename.endswith(".list"):
pkg = basename[:-len(".list")]
f = file(os.path.join(vdir, basename), "r")
for line in f:
pathname = line.strip()
if pathname in vdict:
vdict[pathname].append(pkg)
else:
vdict[pathname] = [pkg]
f.close()
return vdict
def check_for_no_processes(self, fail=None):
"""Check there are no processes running inside the chroot."""
(status, output) = run(["lsof", "-w", "+D", self.name], ignore_errors=True)
count = len(output.split("\n")) - 1
if count > 0:
if fail is None:
fail = not settings.allow_database
logging.error("%s: Processes are running inside chroot:\n%s" %
("FAIL" if fail else "WARN", indent_string(output)))
if fail:
self.terminate_running_processes()
panic()
def terminate_running_processes(self):
"""Terminate all processes running in the chroot."""
seen = []
while True:
p = subprocess.Popen(["lsof", "-t", "+D", self.name],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
stdout, _ = p.communicate()
if not stdout:
break
pidlist = reversed([int(pidstr) for pidstr in stdout.split("\n") if len(pidstr) and int(pidstr) > 0])
if not pidlist:
break
for pid in pidlist:
try:
signo = (SIGTERM, SIGKILL)[pid in seen]
os.kill(pid, signo)
seen.append(pid)
logging.debug("kill -%d %d" % (signo, pid))
time.sleep(0.25)
except OSError:
pass
time.sleep(5)
def mount_selinux(self):
if selinux_enabled():
run(["mkdir", "-p", self.selinuxfs_relative_path()])
run(["mount", "--bind", "/sys/fs/selinux", self.selinuxfs_relative_path()])
run(["mount", "-o", "remount,ro,bind", self.selinuxfs_relative_path()])
logging.info("SElinux mounted into chroot")
def unmount_selinux(self):
if selinux_enabled():
run(["umount", self.selinuxfs_relative_path()])
logging.info("SElinux unmounted from chroot")
# If /selinux is present, assume that this is the only supported
# location by libselinux. Otherwise use the new location.
# /selinux was shipped by the libselinux package until wheezy.
def selinuxfs_relative_path(self):
if os.path.isdir(self.relative('/selinux')):
return self.relative('/selinux')
else:
return self.relative('/sys/fs/selinux')
def mount_proc(self):
"""Mount /proc inside chroot."""
self.run(["mount", "-t", "proc", "proc", "/proc"])
self.mkdir_p("dev/pts")
self.run(["mount", "-o", "gid=5,mode=620", "-t", "devpts", "devpts", "/dev/pts"])
def unmount_proc(self):
"""Unmount /proc inside chroot."""
self.run(["umount", "/proc"], ignore_errors=True)
self.run(["umount", "/dev/pts"], ignore_errors=True)
for bindmount in settings.bindmounts:
run(["umount", self.relative(bindmount)], ignore_errors=True)
def is_ignored(self, pathname):
"""Is a file (or dir or whatever) to be ignored?"""
if pathname in settings.ignored_files:
return True
for pattern in settings.ignored_patterns:
if re.search('^' + pattern + '$', pathname):
return True
return False
def check_for_broken_symlinks(self):
"""Check that all symlinks in chroot are non-broken."""
if not settings.check_broken_symlinks:
return
broken = []
for dirpath, dirnames, filenames in os.walk(self.name):
# Remove /proc within chroot to avoid lots of spurious errors.
if dirpath == self.name and "proc" in dirnames:
dirnames.remove("proc")
for filename in filenames:
full_name = name = os.path.join(dirpath, filename)
if name.startswith(self.name):
name = name[len(self.name):]
ret = is_broken_symlink(self.name, dirpath, filename)
if ret and not self.is_ignored(name):
try:
target = os.readlink(full_name)
except os.error:
target = ""
broken.append("%s -> %s" % (name, target))
if broken:
if settings.warn_broken_symlinks:
logging.error("WARN: Broken symlinks:\n%s" %
indent_string("\n".join(broken)))
else:
logging.error("FAIL: Broken symlinks:\n%s" %
indent_string("\n".join(broken)))
panic()
else:
logging.debug("No broken symlinks as far as we can find.")
def check_if_cronfiles(self, packages):
"""Check if the packages have cron files under /etc/cron.d and in case positive,
it returns the list of files. """
vdir = self.relative("var/lib/dpkg/info")
vlist = []
has_cronfiles = False
for p in packages:
basename = p + ".list"
if not os.path.exists(os.path.join(vdir, basename)):
continue
f = file(os.path.join(vdir, basename), "r")
for line in f:
pathname = line.strip()
if pathname.startswith("/etc/cron."):
if os.path.isfile(self.relative(pathname.strip("/"))):
st = os.lstat(self.relative(pathname.strip("/")))
mode = st[stat.ST_MODE]
# XXX /etc/cron.d/ files are NOT executables
if (mode & stat.S_IEXEC):
if not has_cronfiles:
has_cronfiles = True
vlist.append(pathname)
logging.info("Package " + p + " contains cron file: " + pathname)
f.close()
return has_cronfiles, vlist
def check_output_cronfiles(self, list):
"""Check if a given list of cronfiles has any output. Executes
cron file as cron would do (except for SHELL)"""
failed = False
for vfile in list:
if not os.path.exists(self.relative(vfile.strip("/"))):
continue
(retval, output) = self.run([vfile])
if output:
failed = True
logging.error("FAIL: Cron file %s has output with package removed" % vfile)
if failed:
panic()
def check_if_logrotatefiles(self, packages):
"""Check if the packages have logrotate files under /etc/logrotate.d and in case positive,
it returns the list of files. """
vdir = self.relative("var/lib/dpkg/info")
vlist = []
has_logrotatefiles = False
for p in packages:
basename = p + ".list"
if not os.path.exists(os.path.join(vdir, basename)):
continue
f = file(os.path.join(vdir, basename), "r")
for line in f:
pathname = line.strip()
if pathname.startswith("/etc/logrotate.d/"):
if os.path.isfile(self.relative(pathname.strip("/"))):
if not has_logrotatefiles:
has_logrotatefiles = True
vlist.append(pathname)
logging.info("Package " + p + " contains logrotate file: " + pathname)
f.close()
return has_logrotatefiles, vlist
def install_logrotate(self):
"""Install logrotate for check_output_logrotatefiles, and return the
list of packages that were installed"""
old_selections = self.get_selections()
self.run(['apt-get', 'install', '-y', 'logrotate'])
diff = diff_selections(self, old_selections)
return diff.keys()
def check_output_logrotatefiles(self, list):
"""Check if a given list of logrotatefiles has any output. Executes
logrotate file as logrotate would do from cron (except for SHELL)"""
failed = False
for vfile in list:
if not os.path.exists(self.relative(vfile.strip("/"))):
continue
(retval, output) = self.run(['/usr/sbin/logrotate', vfile])
if output or retval != 0:
failed = True
logging.error("FAIL: Logrotate file %s exits with error or has output with package removed" % file)
if failed:
panic()
def run_scripts(self, step):
""" Run custom scripts to given step post-install|remove|purge"""
if not settings.scriptsdirs:
return
logging.info("Running scripts " + step)
basepath = self.relative("tmp/scripts/")
if not os.path.exists(basepath):
logging.error("Scripts directory %s does not exist" % basepath)
panic()
list_scripts = sorted(os.listdir(basepath))
for vfile in list_scripts:
if vfile.startswith(step):
script = os.path.join("tmp/scripts", vfile)
self.run([script])
class VirtServ(Chroot):
# Provides a thing that looks to the rest of piuparts much like
# a chroot but is actually provided by an adt virtualisation server.
# See /usr/share/doc/autopkgtest/README.virtualisation-server.
def __init__(self, cmdline):
self._cmdline = cmdline
self.name = '/ADT-VIRT'
self._vs = None
def _awaitok(self, cmd):
r = self._vs.stdout.readline().rstrip('\n')
l = r.split(' ')
if l[0] != 'ok':
self._fail('virtserver response to %s: %s' % (cmd, r))
logging.debug('adt-virt << %s', r)
return l[1:]
def _vs_send(self, cmd):
if isinstance(cmd, type([])):
def maybe_quote(a):
if not isinstance(a, type(())):
return a
(a,) = a
return urllib.quote(a)
cmd = ' '.join(map(maybe_quote, cmd))
logging.debug('adt-virt >> %s', cmd)
print >>self._vs.stdin, cmd
return cmd.split(' ')[0]
def _command(self, cmd):
# argument forms: complete-command-string
# [arg, ...] where arg may be (arg,) to quote it
cmdp = self._vs_send(cmd)
self._vs.stdin.flush()
return self._awaitok(cmdp)
def _getfilecontents(self, filename):
try:
(_, tf) = create_temp_file()
self._command(['copyup', (filename,), (tf,)])
f = file(tf)
d = f.read()
f.close()
finally:
os.remove(tf)
return d
def create_temp_dir(self):
if self._vs is None:
logging.debug('adt-virt || %s' % self._cmdline)
self._vs = subprocess.Popen(self._cmdline, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=None)
self._awaitok('banner')
self._caps = self._command('capabilities')
def shutdown(self):
if self._vs is None:
return
self._vs_send('quit')
self._vs.stdin.close()
self._vs.stdout.close()
self._vs.wait()
self._vs = None
def remove(self):
self._command('close')
dont_do_on_panic(self.panic_handler_id)
def _fail(self, m):
logging.error("adt-virt-* error: " + m)
panic()
def _open(self):
self._scratch = self._command('open')[0]
# this is a hack to make install_and_upgrade_between distros
# work; we pretend to save the chroot to a tarball but in
# fact we do nothing and then we can `restore' the `tarball' with
# adt-virt revert
def create_temp_tgz_file(self):
return self
def remove_temp_tgz_file(self, tgz):
if tgz is not self:
self._fail('removing a tgz not supported')
# FIXME: anything else to do here?
def pack_into_tgz(self, tgz):
if tgz is not self:
self._fail('packing into tgz not supported')
if not 'revert' in self._caps:
self._fail('testbed cannot revert')
def unpack_from_tgz(self, tgz):
if tgz is not self:
self._fail('unpacking from tgz not supported')
self._open()
def _execute(self, cmdl, tolerate_errors=False):
assert isinstance(cmdl, type([]))
prefix = ['sh', '-ec', '''
LC_ALL=C
unset LANGUAGES
export LC_ALL
exec 2>&1
exec "$@"
''', '']
ca = ','.join(map(urllib.quote, prefix + cmdl))
stdout = '%s/cmd-stdout' % self._scratch
stderr = '%s/cmd-stderr-base' % self._scratch
cmd = ['execute', ca,
'/dev/null', (stdout,), (stderr,),
'/root', 'timeout=600']
es = int(self._command(cmd)[0])
if es and not tolerate_errors:
stderr_data = self._getfilecontents(stderr)
logging.error("Execution failed (status=%d): %s\n%s" %
(es, repr(cmdl), indent_string(stderr_data)))
panic()
return (es, stdout, stderr)
def _execute_getoutput(self, cmdl):
(es, stdout, stderr) = self._execute(cmdl)
stderr_data = self._getfilecontents(stderr)
if es or stderr_data:
logging.error('Internal command failed (status=%d): %s\n%s' %
(es, repr(cmdl), indent_string(stderr_data)))
panic()
(_, tf) = create_temp_file()
try:
self._command(['copyup', (stdout,), (tf,)])
except:
os.remove(tf)
raise
return tf
def run(self, command, ignore_errors=False):
cmdl = ['sh', '-ec', 'cd /\n' + ' '.join(command)]
(es, stdout, stderr) = self._execute(cmdl, tolerate_errors=True)
stdout_data = self._getfilecontents(stdout)
print >>sys.stderr, "VirtServ run", repr(command), repr(cmdl), '==>', repr(es), repr(stdout), repr(stderr), '|', stdout_data
if es == 0 or ignore_errors:
return (es, stdout_data)
stderr_data = self._getfilecontents(stderr)
logging.error('Command failed (status=%d): %s\n%s' %
(es, repr(command), indent_string(stdout_data + stderr_data)))
panic()
def setup_minimal_chroot(self):
self._open()
def _tbpath(self, with_junk):
if not with_junk.startswith(self.name):
logging.error("Un-mangling testbed path `%s' but it does not"
"start with expected manglement `%s'" %
(with_junk, self.name))
panic()
return with_junk[len(self.name):]
def chmod(self, path, mode):
self._execute(['chmod', ('0%o' % mode), self._tbpath(path)])
def remove_files(self, paths):
self._execute(['rm', '--'] + map(self._tbpath, paths))
def copy_file(self, our_src, tb_dest):
self._command(['copydown', (our_src,),
(self._tbpath(tb_dest) + '/' + os.path.basename(our_src),)])
def create_file(self, path, data):
path = self._tbpath(path)
try:
(_, tf) = create_temp_file()
f = file(tf, 'w')
f.write(tf)
f.close()
self._command(['copydown', (tf,), (path,)])
finally:
os.remove(tf)
class DummyStat:
pass
def save_meta_data(self):
mode_map = {
's': stat.S_IFSOCK,
'l': stat.S_IFLNK,
'f': stat.S_IFREG,
'b': stat.S_IFBLK,
'd': stat.S_IFDIR,
'c': stat.S_IFCHR,
'p': stat.S_IFIFO,
}
vdict = {}
tf = self._execute_getoutput(['find', '/', '-xdev', '-printf',
"%y %m %U %G %s %p %l \\n".replace(' ', '\\0')])
try:
f = file(tf)
while True:
line = ''
while True:
splut = line.split('\0')
if len(splut) == 8 and splut[7] == '\n':
break
if len(splut) >= 8:
self._fail('aaargh wrong output from find: %s' %
urllib.quote(line), repr(splut))
l = f.readline()
if not l:
if not line:
break
self._fail('aargh missing final newline from find'
': %s, %s' % (repr(l)[0:200], repr(splut)[0:200]))
line += l
if not line:
break
st = VirtServ.DummyStat()
st.st_mode = mode_map[splut[0]] | int(splut[1], 8)
(st.st_uid, st.st_gid, st.st_size) = map(int, splut[2:5])
vdict[splut[5]] = (st, splut[6])
f.close()
finally:
os.remove(tf)
return vdict
def get_files_owned_by_packages(self):
tf = self._execute_getoutput(['bash', '-ec', '''
cd /var/lib/dpkg/info
find . -name "*.list" -type f -print0 | \\
xargs -r0 egrep . /dev/null
test "${PIPESTATUS[*]}" = "0 0"
'''])
vdict = {}
try:
f = file(tf)
for l in f:
(lf, pathname) = l.rstrip('\n').split(':', 1)
assert lf.endswith('.list')
pkg = lf[:-5]
if pathname in vdict:
vdict[pathname].append(pkg)
else:
vdict[pathname] = [pkg]
f.close()
finally:
os.remove(tf)
return vdict
def check_for_broken_symlinks(self):
if not settings.check_broken_symlinks:
return
tf = self._execute_getoutput(['bash', '-ec', '''
find / -xdev -type l -print0 | \\
xargs -r0 -i'{}' \\
find '{}' -maxdepth 0 -follow -type l -ls
test "${PIPESTATUS[*]}" = "0 0"
'''])
try:
f = file(tf)
broken = False
for l in f:
logging.error("FAIL: Broken symlink: " + l)
broken = True
if broken:
panic()
logging.debug("No broken symlinks found.")
finally:
os.remove(tf)
def check_for_no_processes(self):
pass # ?!
def mount_proc(self):
pass
def unmount_proc(self):
pass
def selinux_enabled(enabled_test="/usr/sbin/selinuxenabled"):
if os.access(enabled_test, os.X_OK):
retval, output = run([enabled_test], ignore_errors=True)
if retval == 0:
return True
else:
return False
def objects_are_different(pair1, pair2):
"""Are filesystem objects different based on their meta data?"""
(m1, target1) = pair1
(m2, target2) = pair2
if (m1.st_mode != m2.st_mode or
m1.st_uid != m2.st_uid or
m1.st_gid != m2.st_gid or
target1 != target2):
return True
if stat.S_ISREG(m1.st_mode):
return m1.st_size != m2.st_size # or m1.st_mtime != m2.st_mtime
return False
def format_object_attributes(pair):
(st, target) = pair
ft = ""
if stat.S_ISDIR(st.st_mode):
ft += "d"
if stat.S_ISCHR(st.st_mode):
ft += "c"
if stat.S_ISBLK(st.st_mode):
ft += "b"
if stat.S_ISREG(st.st_mode):
ft += "-"
if stat.S_ISFIFO(st.st_mode):
ft += "p"
if stat.S_ISLNK(st.st_mode):
ft += "l"
if stat.S_ISSOCK(st.st_mode):
ft += "s"
res = "(%d, %d, %s %o, %d, %s)" % (
st.st_uid,
st.st_gid,
ft,
st.st_mode,
st.st_size,
target)
return res
def diff_meta_data(tree1, tree2):
"""Compare two dir trees and return list of new files (only in 'tree2'),
removed files (only in 'tree1'), and modified files."""
tree1 = tree1.copy()
tree2 = tree2.copy()
for name in settings.ignored_files:
if name in tree1:
del tree1[name]
if name in tree2:
del tree2[name]
for pattern in settings.ignored_patterns:
pat = re.compile(pattern)
for name in tree1.keys():
m = pat.search(name)
if m:
del tree1[name]
for name in tree2.keys():
m = pat.search(name)
if m:
del tree2[name]
modified = []
for name in tree1.keys()[:]:
if name in tree2:
if objects_are_different(tree1[name], tree2[name]):
logging.debug("Modified(uid, gid, mode, size, target): %s %s != %s" %
(name, format_object_attributes(tree1[name]), format_object_attributes(tree2[name])))
modified.append((name, tree1[name]))
del tree1[name]
del tree2[name]
removed = [x for x in tree1.iteritems()]
new = [x for x in tree2.iteritems()]
# fix for #586793
# prune rc?.d symlinks renamed by insserv
pat1 = re.compile(r"^(/etc/rc.\.d/)[SK][0-9]{2}(.*)$")
for name1, data1 in removed[:]:
m = pat1.search(name1)
if m:
pat2 = re.compile(r"^" + m.group(1) + r"[SK][0-9]{2}" + m.group(2) + r"$")
for name2, data2 in new[:]:
m = pat2.search(name2)
if m:
logging.debug("File was renamed: %s\t=> %s" % (name1, name2))
removed.remove((name1, data1))
new.remove((name2, data2))
# this is again special casing due to the behaviour of a single package :(
# general tracking of moved files would be the better approach, probably.
return new, removed, modified
def file_list(meta_infos, file_owners):
"""Return list of indented filenames."""
meta_infos = sorted(meta_infos[:])
vlist = []
for name, data in meta_infos:
(st, target) = data
info = ""
if target is not None:
info = " -> %s" % target
vlist.append(" %s%s\t" % (name, info))
key = name
if key.endswith('/'):
key = key[:-1]
if key in file_owners:
vlist.append(" owned by: %s\n" % ", ".join(file_owners[key]))
else:
vlist.append(" not owned\n")
return "".join(vlist)
def offending_packages(meta_infos, file_owners):
"""Return a Set of offending packages."""
pkgset = set()
for name, data in meta_infos:
if name in file_owners:
for pkg in file_owners[name]:
pkgset.add(pkg)
return pkgset
def prune_files_list(files, depsfiles):
"""Remove elements from 'files' that are in 'depsfiles', and return the
list of removed elements.
"""
warn = []
depfiles_names = [x[0] for x in depsfiles]
for vfile in files[:]:
if vfile[0] in depfiles_names:
files.remove(vfile)
warn.append(vfile)
return warn
def diff_selections(chroot, selections):
"""Compare original and current package selection.
Return dict where dict[package_name] = original_status, that is,
the value in the dict is the state that the package needs to be
set to to restore original selections."""
changes = {}
current = chroot.get_selections()
for name, (value, version) in current.iteritems():
if name not in selections:
changes[name] = ("purge", None)
elif selections[name][0] != value and \
selections[name][0] in ["purge", "install"]:
changes[name] = selections[name]
for name, (value, version) in selections.iteritems():
if name not in current or \
current[name][1] != version:
changes[name] = selections[name]
return changes
def get_package_names_from_package_files(package_files):
"""Return list of package names given list of package file names."""
vlist = []
for filename in package_files:
(status, output) = run(["dpkg", "--info", filename])
p = None
v = None
for line in [line.lstrip() for line in output.split("\n")]:
if line.startswith("Package:"):
p = line.split(":", 1)[1].strip()
if line.startswith("Version:"):
v = line.split(":", 1)[1].strip()
if p is not None:
if v is not None:
vlist.append(p + "=" + v)
else:
vlist.append(p)
return vlist
# Method to process a changes file, returning a list of all the .deb packages
# from the 'Files' stanza.
def process_changes(changes):
# Determine the path to the changes file, then check if it's readable.
dir_path = ""
changes_path = ""
if not os.path.dirname(changes):
changes_path = os.path.basename(changes)
else:
dir_path = os.path.dirname(changes) + "/"
changes_path = os.path.abspath(changes)
if not os.access(changes_path, os.R_OK):
logging.warn(changes_path + " is not readable. Skipping.")
return
# Determine the packages in the changes file through the 'Files' stanza.
field = 'Files'
pattern = re.compile(
r'^' + field + r':' + r''' # The field we want the contents from
(.*?) # The contents of the field
\n([^ ]|$) # Start of a new field or EOF
''',
re.MULTILINE | re.DOTALL | re.VERBOSE)
f = open(changes_path)
file_text = f.read()
f.close()
matches = pattern.split(file_text)
# Append all the packages found in the changes file to a package list.
package_list = []
newline_p = re.compile('\n')
package_p = re.compile('.*?([^ ]+\.deb)$')
for line in newline_p.split(matches[1]):
if package_p.match(line):
package = dir_path + package_p.split(line)[1]
package_list.append(package)
# Return the list.
return package_list
def check_results(chroot, chroot_state, file_owners, deps_info=None):
"""Check that current chroot state matches 'chroot_state'.
If settings.warn_on_others is True and deps_info is not None, then only
print a warning rather than failing if the current chroot contains files
that are in deps_info but not in root_info. (In this case, deps_info
should be the result of chroot.save_meta_data() right after the
dependencies are installed, but before the actual packages to test are
installed.)
"""
root_info = chroot_state["tree"]
ok = True
if settings.check_broken_diversions:
(removed, added) = chroot.get_modified_diversions(chroot_state["diversions"])
if added:
logging.error("FAIL: Installed diversions (dpkg-divert) not removed by purge:\n%s" %
indent_string("\n".join(added)))
ok = False
if removed:
logging.error("FAIL: Existing diversions (dpkg-divert) removed/modified:\n%s" %
indent_string("\n".join(removed)))
ok = False
current_info = chroot.save_meta_data()
if settings.warn_on_others and deps_info is not None:
(new, removed, modified) = diff_meta_data(root_info, current_info)
(depsnew, depsremoved, depsmodified) = diff_meta_data(root_info,
deps_info)
warnnew = prune_files_list(new, depsnew)
warnremoved = prune_files_list(removed, depsremoved)
warnmodified = prune_files_list(modified, depsmodified)
else:
(new, removed, modified) = diff_meta_data(root_info, current_info)
if new:
if settings.warn_on_leftovers_after_purge:
logging.info("Warning: Package purging left files on system:\n" +
file_list(new, file_owners))
else:
logging.error("FAIL: Package purging left files on system:\n" +
file_list(new, file_owners))
ok = False
if removed:
logging.error("FAIL: After purging files have disappeared:\n" +
file_list(removed, file_owners))
ok = False
if modified:
logging.error("FAIL: After purging files have been modified:\n" +
file_list(modified, file_owners))
ok = False
if settings.warn_on_others and deps_info is not None:
if warnnew:
msg = ("Warning: Package purging left files on system:\n" +
file_list(warnnew, file_owners) +
"These files seem to have been left by dependencies rather "
"than by packages\nbeing explicitly tested.\n")
logging.info(msg)
if warnremoved:
msg = ("After purging files have disappeared:\n" +
file_list(warnremoved, file_owners) +
"This seems to have been caused by dependencies rather "
"than by packages\nbeing explicitly tested.\n")
logging.info(msg)
if warnmodified:
msg = ("After purging files have been modified:\n" +
file_list(warnmodified, file_owners) +
"This seems to have been caused by dependencies rather "
"than by packages\nbeing explicitly tested.\n")
logging.info(msg)
return ok
def install_purge_test(chroot, chroot_state, package_files, packages, extra_packages):
"""Do an install-purge test. Return True if successful, False if not.
Assume 'root' is a directory already populated with a working
chroot, with packages in states given by 'selections'."""
deps_info = None
os.environ["PIUPARTS_TEST"] = "install"
chroot.run_scripts("pre_test")
# Install packages into the chroot.
os.environ["PIUPARTS_PHASE"] = "install"
chroot.enable_testdebs_repo()
chroot.check_for_no_processes(fail=True)
chroot.check_for_broken_symlinks()
chroot.run_scripts("pre_install")
chroot.install_packages([], extra_packages, with_scripts=False)
if settings.warn_on_others or settings.install_purge_install:
# Create a metapackage with dependencies from the given packages
if package_files:
control_infos = []
# We were given package files, so let's get the Depends and
# Conflicts directly from the .debs
for deb in package_files:
returncode, output = run(["dpkg", "-f", deb])
control = deb822.Deb822(output)
control_infos.append(control)
else:
# We have package names. Use apt to get all their control
# information.
apt_cache_args = ["apt-cache", "show"]
if os.environ["PIUPARTS_DISTRIBUTION"] in ["lenny"]:
# apt-cache in lenny does not accept version-qualified packages
apt_cache_args.extend(unqualify(packages))
else:
apt_cache_args.extend(packages)
returncode, output = chroot.run(apt_cache_args)
control_infos = deb822.Deb822.iter_paragraphs(output.splitlines())
depends = []
conflicts = []
provides = []
for control in control_infos:
if control.get("pre-depends"):
depends.extend([x.strip() for x in control["pre-depends"].split(',')])
if control.get("depends"):
depends.extend([x.strip() for x in control["depends"].split(',')])
if control.get("conflicts"):
conflicts.extend([x.strip() for x in control["conflicts"].split(',')])
if control.get("provides"):
provides.extend([x.strip() for x in control["provides"].split(',')])
for provided in provides:
if provided in conflicts:
conflicts.remove(provided)
all_depends = ", ".join(depends)
all_conflicts = ", ".join(conflicts)
metapackage = make_metapackage("piuparts-depends-dummy",
all_depends, all_conflicts)
cleanup_metapackage = lambda: shutil.rmtree(os.path.dirname(metapackage))
panic_handler_id = do_on_panic(cleanup_metapackage)
# Install the metapackage
chroot.install_package_files([metapackage], with_scripts=False)
if not chroot.is_installed(["piuparts-depends-dummy"]):
logging.error("Installation of piuparts-depends-dummy FAILED")
# FIXME: too many failures
# panic()
# Now remove it
metapackagename = os.path.basename(metapackage)[:-4]
chroot.purge_packages([metapackagename])
cleanup_metapackage()
dont_do_on_panic(panic_handler_id)
# Save the file ownership information so we can tell which
# modifications were caused by the actual packages we are testing,
# rather than by their dependencies.
deps_info = chroot.save_meta_data()
if settings.install_purge_install:
# save chroot state with all deps installed
chroot_state_with_deps = {}
chroot_state_with_deps["tree"] = deps_info
chroot_state_with_deps["selections"] = chroot.get_selections()
chroot_state_with_deps["diversions"] = chroot.get_diversions()
chroot.check_for_no_processes()
chroot.check_for_broken_symlinks()
chroot.install_packages(package_files, packages, with_scripts=False)
chroot.run_scripts("post_install")
if settings.install_purge_install:
file_owners = chroot.get_files_owned_by_packages()
chroot.restore_selections(chroot_state_with_deps["selections"], packages)
logging.info("Validating chroot after purge")
chroot.check_debsums()
chroot.check_for_no_processes()
chroot.check_for_broken_symlinks()
if not check_results(chroot, chroot_state_with_deps, file_owners, deps_info=deps_info):
return False
logging.info("Reinstalling after purge")
chroot.install_packages(package_files, packages, with_scripts=True)
if settings.install_remove_install:
chroot.remove_packages(packages)
logging.info("Reinstalling after remove")
chroot.install_packages(package_files, packages, with_scripts=True)
chroot.check_for_no_processes()
chroot.check_for_broken_symlinks()
file_owners = chroot.get_files_owned_by_packages()
chroot.disable_testdebs_repo()
# Remove all packages from the chroot that weren't there initially.
chroot.restore_selections(chroot_state["selections"], packages)
chroot.check_for_no_processes(fail=True)
chroot.check_for_broken_symlinks()
return check_results(chroot, chroot_state, file_owners, deps_info=deps_info)
def install_upgrade_test(chroot, chroot_state, package_files, packages, old_packages):
"""Install old_packages via apt-get, then upgrade from package files.
Return True if successful, False if not."""
os.environ["PIUPARTS_TEST"] = "upgrade"
chroot.run_scripts("pre_test")
# First install via apt-get.
os.environ["PIUPARTS_PHASE"] = "install"
chroot.install_packages_by_name(old_packages)
chroot.check_for_no_processes()
chroot.check_for_broken_symlinks()
if settings.install_remove_install:
chroot.remove_packages(packages)
# Then from the package files.
os.environ["PIUPARTS_PHASE"] = "upgrade"
chroot.enable_testdebs_repo()
chroot.install_packages(package_files, packages)
chroot.check_for_no_processes()
chroot.check_for_broken_symlinks()
file_owners = chroot.get_files_owned_by_packages()
chroot.disable_testdebs_repo()
# Remove all packages from the chroot that weren't there initially.
chroot.restore_selections(chroot_state["selections"], packages)
chroot.check_for_no_processes(fail=True)
chroot.check_for_broken_symlinks()
return check_results(chroot, chroot_state, file_owners)
def save_meta_data(filename, chroot_state):
"""Save directory tree meta data into a file for fast access later."""
logging.debug("Saving chroot meta data to %s" % filename)
f = file(filename, "w")
pickle.dump(chroot_state, f)
f.close()
def load_meta_data(filename):
"""Load meta data saved by 'save_meta_data'."""
logging.debug("Loading chroot meta data from %s" % filename)
f = file(filename, "r")
chroot_state = pickle.load(f)
f.close()
return chroot_state
def install_and_upgrade_between_distros(package_files, packages_qualified):
"""Install package and upgrade it between distributions, then remove.
Return True if successful, False if not."""
# this function is a bit confusing at first, because of what it does by default:
# 1. create chroot with source distro
# 2. upgrade chroot to target distro
# 3. remove chroot and recreate chroot with source distro
# 4. install depends in chroot
# 5. install package in chroot
# 6. upgrade chroot to target distro
# 7. remove package and depends
# 8. compare results
#
# sounds silly, or?
# well, it is a reasonable default (see below for why), but
# step 2+3 can be done differently by using --save-end-meta once and
# then --end-meta for all following runs - until the target distro
# changes again...
#
# Under normal circumstances the target distro can change anytime, ie. at
# the next mirror pulse, so unless the target distro is frozen, this is
# a reasonable default behaviour for distro upgrade tests, which are not
# done by default anyway.
os.environ["PIUPARTS_TEST"] = "distupgrade"
packages = unqualify(packages_qualified)
chroot = get_chroot()
chroot.create()
if settings.end_meta:
# load root_info and selections
chroot_state = load_meta_data(settings.end_meta)
else:
temp_tgz = None
if chroot.was_bootstrapped():
temp_tgz = chroot.create_temp_tgz_file()
panic_handler_id = do_on_panic(lambda: chroot.remove_temp_tgz_file(temp_tgz))
chroot.pack_into_tgz(temp_tgz)
chroot.upgrade_to_distros(settings.debian_distros[1:], [])
chroot.check_for_no_processes(fail=True)
# set root_info and selections
chroot_state = {}
chroot_state["tree"] = chroot.save_meta_data()
chroot_state["selections"] = chroot.get_selections()
chroot_state["diversions"] = chroot.get_diversions()
if settings.save_end_meta:
# save root_info and selections
save_meta_data(settings.save_end_meta, chroot_state)
chroot.remove()
# leave indication in logfile why we do what we do
logging.info(
"Notice: package selections and meta data from target distro saved, now starting over from source distro. See the description of --save-end-meta and --end-meta to learn why this is neccessary and how to possibly avoid it.")
chroot = get_chroot()
if temp_tgz is None:
chroot.create()
else:
chroot.create(temp_tgz)
chroot.remove_temp_tgz_file(temp_tgz)
dont_do_on_panic(panic_handler_id)
chroot.check_for_no_processes(fail=True)
chroot.run_scripts("pre_test")
os.environ["PIUPARTS_PHASE"] = "install"
distupgrade_packages = packages
known_packages = chroot.get_known_packages(packages + settings.extra_old_packages)
chroot.install_packages_by_name(known_packages)
if settings.install_remove_install:
chroot.remove_packages(packages)
distupgrade_packages = []
chroot.check_for_no_processes()
os.environ["PIUPARTS_PHASE"] = "distupgrade"
chroot.upgrade_to_distros(settings.debian_distros[1:-1], distupgrade_packages)
if settings.distupgrade_to_testdebs:
chroot.enable_testdebs_repo(update=False)
chroot.upgrade_to_distros(settings.debian_distros[-1:], distupgrade_packages)
chroot.check_for_no_processes()
os.environ["PIUPARTS_PHASE"] = "upgrade"
if not settings.distupgrade_to_testdebs:
chroot.enable_testdebs_repo()
chroot.install_packages(package_files, [p for p in packages_qualified if not p.endswith("=None")])
chroot.disable_testdebs_repo()
chroot.check_for_no_processes()
file_owners = chroot.get_files_owned_by_packages()
# Remove all packages from the chroot that weren't in the reference chroot.
chroot.restore_selections(chroot_state["selections"], packages_qualified)
chroot.check_for_no_processes(fail=True)
result = check_results(chroot, chroot_state, file_owners)
chroot.remove()
return result
def parse_mirror_spec(str, defaultcomponents=[]):
"""Parse a mirror specification from the --mirror option argument.
Return (mirror, componentslist)."""
parts = str.split()
return parts[0], parts[1:] or defaultcomponents[:]
def find_default_debian_mirrors():
"""Find the default Debian mirrors."""
mirrors = []
try:
f = file("/etc/apt/sources.list", "r")
for line in f:
line = re.sub('\[arch=.*\]', '', line)
parts = line.split()
if len(parts) > 2 and parts[0] == "deb":
mirrors.append((parts[1], parts[3:]))
break # Only use the first one, at least for now.
f.close()
except IOError:
return None
return mirrors
def forget_ignores(option, opt, value, parser, *args, **kwargs):
settings.bindmounts = []
parser.values.ignore = []
parser.values.ignore_regex = []
settings.ignored_files = []
settings.ignored_patterns = []
def set_basetgz_to_pbuilder(option, opt, value, parser, *args, **kwargs):
parser.values.basetgz = "/var/cache/pbuilder/base.tgz"
def parse_command_line():
"""Parse the command line, change global settings, return non-options."""
parser = optparse.OptionParser(usage="%prog [options] package ...",
version="piuparts %s" % VERSION)
parser.add_option("-a", "--apt", action="store_true", default=False,
help="Command line arguments are package names " +
"to be installed via apt.")
parser.add_option("--arch", metavar="ARCH", action="store",
help="Create chroot and run tests for (non-default) architecture ARCH.")
parser.add_option("--adt-virt",
metavar='CMDLINE', default=None,
help="Use CMDLINE via autopkgtest (adt-virt-*)"
" protocol instead of managing a chroot.")
parser.add_option("-b", "--basetgz", metavar="TARBALL",
help="Use TARBALL as the contents of the initial " +
"chroot, instead of building a new one with " +
"debootstrap.")
parser.add_option("--bindmount", action="append", metavar="DIR",
default=[],
help="Directory to be bind-mounted inside the chroot.")
parser.add_option("-d", "--distribution", action="append", metavar="NAME",
help="Which Debian distribution to use: a code name " +
"(for example jessie, stretch, sid) or experimental. The " +
"default is sid (=unstable).")
parser.add_option("-D", "--defaults", action="store",
help="Choose which set of defaults to use "
"(debian/ubuntu).")
parser.add_option("--debfoster-options",
default="-o MaxPriority=required -o UseRecommends=no -f -n apt debfoster",
help="Run debfoster with different parameters (default: -o MaxPriority=required -o UseRecommends=no -f -n apt debfoster).")
parser.add_option("--no-eatmydata",
default=False,
action='store_true',
help="Default is to use libeatmydata in the chroot")
parser.add_option("--dpkg-noforce-unsafe-io",
default=False,
action='store_true',
help="Default is to run dpkg with --force-unsafe-io option, which causes dpkg to skip certain file system syncs known to cause substantial performance degradation on some filesystems. This option turns that off and dpkg will use safe I/O operations.")
parser.add_option("--dpkg-force-confdef",
default=False,
action='store_true',
help="Make dpkg use --force-confdef, which lets dpkg always choose the default action when a modified conffile is found. This option will make piuparts ignore errors it was designed to report and therefore should only be used to hide problems in depending packages. (See #466118.)")
parser.add_option("--do-not-verify-signatures", default=False,
action='store_true',
help="Do not verify signatures from the Release files when running debootstrap.")
parser.add_option("--allow-database", default=False,
action='store_true',
help="Allow database servers (MySQL, PostgreSQL) to be started in the chroot.")
parser.add_option("--distupgrade-to-testdebs", default=False,
action='store_true',
help="Use the testdebs repository as distupgrade target.")
parser.add_option("-e", "--existing-chroot", metavar="DIR",
help="Use DIR as the contents of the initial " +
"chroot, instead of building a new one with " +
"debootstrap")
parser.add_option("-i", "--ignore", action="append", metavar="FILENAME",
default=[],
help="Add FILENAME to list of filenames to be " +
"ignored when comparing changes to chroot.")
parser.add_option("-I", "--ignore-regex", action="append",
metavar="REGEX", default=[],
help="Add REGEX to list of Perl compatible regular " +
"expressions for filenames to be " +
"ignored when comparing changes to chroot.")
parser.add_option("--install-recommends",
action="store_true", default=False,
help="Enable the installation of Recommends.")
parser.add_option("-k", "--keep-tmpdir",
action="store_true", default=False,
help="Don't remove the temporary directory for the " +
"chroot when the program ends.")
parser.add_option("-K", "--keyring", action="store", metavar="FILE",
help="Use FILE as the keyring to use with debootstrap when creating chroots.")
parser.add_option("--keep-sources-list",
action="store_true", default=False,
help="Don't modify the chroot's " +
"etc/apt/sources.list (only makes sense " +
"with --basetgz).")
parser.add_option("-l", "--log-file", metavar="FILENAME",
help="Write log file to FILENAME in addition to " +
"the standard output.")
parser.add_option("--list-installed-files",
action="store_true", default=False,
help="List files added to the chroot after the " +
"installation of the package.")
parser.add_option("--lvm-volume", metavar="LVM-VOL", action="store",
help="Use LVM-VOL as source for the chroot, instead of building " +
"a new one with debootstrap. This creates a snapshot of the " +
"given LVM volume and mounts it to the chroot path")
parser.add_option("--lvm-snapshot-size", metavar="SNAPSHOT-SIZE", action="store",
default="1G", help="Use SNAPSHOT-SIZE as snapshot size when creating " +
"a new LVM snapshot (default: 1G)")
parser.add_option("--schroot", metavar="SCHROOT-NAME", action="store",
help="Use schroot session named SCHROOT-NAME for the chroot, instead of building " +
"a new one with debootstrap.")
parser.add_option("-m", "--mirror", action="append", metavar="URL",
default=[],
help="Which Debian mirror to use.")
parser.add_option("--extra-repo", action="append",
default=[],
help="Additional (unparsed) lines to be appended to sources.list, e.g. " +
"'deb ' or 'deb file:// ./'")
parser.add_option("--testdebs-repo",
help="A repository that contains the packages to be tested, e.g. " +
"'deb ...' or 'deb file:// ./'," +
"plain URLs or local paths are permitted, too.")
parser.add_option("--no-adequate",
default=False,
action='store_true',
help="Don't run adequate after installation.")
parser.add_option("--no-diversions", action="store_true",
default=False,
help="Don't check for broken diversions.")
parser.add_option("-n", "--no-ignores", action="callback",
callback=forget_ignores,
help="Forget all ignores set so far, including " +
"built-in ones.")
parser.add_option("-N", "--no-symlinks", action="store_true",
default=False,
help="Don't check for broken symlinks.")
parser.add_option("--no-upgrade-test",
action="store_true", default=False,
help="Skip testing the upgrade from an existing version " +
"in the archive.")
parser.add_option("--no-install-purge-test",
action="store_true", default=False,
help="Skip install and purge test.")
parser.add_option("--install-purge-install",
action="store_true", default=False,
help="Purge package after installation and reinstall.")
parser.add_option("--install-remove-install",
action="store_true", default=False,
help="Remove package after installation and reinstall. For testing installation in config-files-remaining state.")
parser.add_option("--extra-old-packages",
action="append", default=[],
help="Install these additional packages along with the old packages from the archive. " +
"Useful to test Conflicts/Replaces of packages that will disappear during the update. " +
"Takes a comma separated list of package names and can be given multiple times. " +
"For install/purge tests these packages will be installed before the package that is to be tested.")
parser.add_option("-p", "--pbuilder", action="callback",
callback=set_basetgz_to_pbuilder,
help="Use /var/cache/pbuilder/base.tgz as the base " +
"tarball.")
parser.add_option("--pedantic-purge-test",
action="store_true", default=False,
help="Be pedantic when checking if a purged package leaves files behind. If this option is not set, files left in /tmp are ignored.")
parser.add_option("--proxy", metavar="URL",
help="Use the proxy at URL for accessing the mirrors.")
parser.add_option("-s", "--save", metavar="FILENAME",
help="Save the chroot into FILENAME.")
parser.add_option("-B", "--end-meta", metavar="FILE",
help="Load chroot package selection and file meta data from FILE. See the function install_and_upgrade_between_distros() in piuparts.py for defaults. Mostly useful for large scale distro upgrade tests.")
parser.add_option("-S", "--save-end-meta", metavar="FILE",
help="Save chroot package selection and file meta data in FILE for later use. See the function install_and_upgrade_between_distros() in piuparts.py for defaults. Mostly useful for large scale distro upgrade tests.")
parser.add_option("--single-changes-list", default=False,
action="store_true",
help="test all packages from all changes files together.")
parser.add_option("--skip-cronfiles-test",
action="store_true", default=False,
help="Skip testing the output from the cron files.")
parser.add_option("--skip-logrotatefiles-test",
action="store_true", default=False,
help="Skip testing the output from the logrotate files.")
parser.add_option("--skip-minimize",
action="store_true", default=True,
help="Skip minimize chroot step. This is the default now.")
parser.add_option("--minimize",
action="store_true", default=False,
help="Minimize chroot with debfoster. This used to be the default until #539142 was fixed.")
parser.add_option("--scriptsdir", metavar="DIR",
action="append", default=[],
help="Directory where are placed the custom scripts. Can be given multiple times.")
parser.add_option("-t", "--tmpdir", metavar="DIR",
help="Use DIR for temporary storage. Default is " +
"$TMPDIR or /tmp.")
parser.add_option("-v", "--verbose",
action="store_true", default=False,
help="No meaning anymore.")
parser.add_option("--warn-on-others",
action="store_true", default=False,
help="Print a warning rather than failing if "
"files are left behind, modified, or removed "
"by a package that was not given on the "
"command-line. Behavior with multiple packages "
"given could be problematic, particularly if the "
"dependency tree of one package in the list "
"includes another in the list. Therefore, it is "
"recommended to use this option with one package "
"at a time.")
parser.add_option("--warn-on-leftovers-after-purge",
action="store_true", default=False,
help="Print a warning rather than failing if "
"files are left behind after purge.")
parser.add_option("--warn-on-debsums-errors",
action="store_true", default=False,
help="Print a warning rather than failing if "
"debsums reports modified files.")
parser.add_option("--fail-if-inadequate",
action="store_true", default=False,
help="Fail on inadequate results from running adequate.")
parser.add_option("--fail-on-broken-symlinks", action="store_true",
default=False,
help="Fail if broken symlinks are detected.")
parser.add_option("--log-level", action="store", metavar='LEVEL',
default="dump",
help="Displays messages from LEVEL level, possible values are: error, info, dump, debug. The default is dump.")
(opts, args) = parser.parse_args()
settings.defaults = opts.defaults
defaults = DefaultsFactory().new_defaults()
settings.tmpdir = opts.tmpdir
settings.keep_tmpdir = opts.keep_tmpdir
settings.single_changes_list = opts.single_changes_list
settings.args_are_package_files = not opts.apt
# distro setup
settings.proxy = opts.proxy
if settings.proxy:
os.environ["http_proxy"] = settings.proxy
settings.debian_mirrors = [parse_mirror_spec(x, defaults.get_components())
for x in opts.mirror]
settings.extra_repos = opts.extra_repo
settings.testdebs_repo = opts.testdebs_repo
settings.debian_distros = opts.distribution
settings.keep_sources_list = opts.keep_sources_list
if opts.keyring:
settings.keyring = opts.keyring
else:
settings.keyring = defaults.get_keyring()
settings.do_not_verify_signatures = opts.do_not_verify_signatures
if settings.do_not_verify_signatures:
settings.apt_unauthenticated = "Yes"
else:
settings.apt_unauthenticated = "No"
settings.install_recommends = opts.install_recommends
settings.eatmydata = not opts.no_eatmydata
settings.dpkg_force_unsafe_io = not opts.dpkg_noforce_unsafe_io
settings.dpkg_force_confdef = opts.dpkg_force_confdef
settings.scriptsdirs = opts.scriptsdir
settings.bindmounts += opts.bindmount
settings.allow_database = opts.allow_database
# chroot setup
settings.arch = opts.arch
settings.basetgz = opts.basetgz
settings.savetgz = opts.save
settings.lvm_volume = opts.lvm_volume
settings.lvm_snapshot_size = opts.lvm_snapshot_size
settings.existing_chroot = opts.existing_chroot
settings.schroot = opts.schroot
settings.end_meta = opts.end_meta
settings.save_end_meta = opts.save_end_meta
settings.skip_minimize = opts.skip_minimize
settings.minimize = opts.minimize
if settings.minimize:
settings.skip_minimize = False
settings.debfoster_options = opts.debfoster_options.split()
# tests and checks
settings.no_install_purge_test = opts.no_install_purge_test
settings.no_upgrade_test = opts.no_upgrade_test
settings.distupgrade_to_testdebs = opts.distupgrade_to_testdebs
settings.install_purge_install = opts.install_purge_install
settings.install_remove_install = opts.install_remove_install
settings.list_installed_files = opts.list_installed_files
[settings.extra_old_packages.extend([i.strip() for i in csv.split(",")]) for csv in opts.extra_old_packages]
settings.skip_cronfiles_test = opts.skip_cronfiles_test
settings.skip_logrotatefiles_test = opts.skip_logrotatefiles_test
settings.adequate = not opts.no_adequate
settings.check_broken_diversions = not opts.no_diversions
settings.check_broken_symlinks = not opts.no_symlinks
settings.warn_broken_symlinks = not opts.fail_on_broken_symlinks
settings.warn_on_others = opts.warn_on_others
settings.warn_on_leftovers_after_purge = opts.warn_on_leftovers_after_purge
settings.warn_on_debsums_errors = opts.warn_on_debsums_errors
settings.warn_if_inadequate = not opts.fail_if_inadequate
settings.pedantic_purge_test = opts.pedantic_purge_test
settings.ignored_files += opts.ignore
settings.ignored_patterns += opts.ignore_regex
if not settings.pedantic_purge_test:
settings.ignored_patterns += settings.non_pedantic_ignore_patterns
if opts.adt_virt is None:
settings.adt_virt = None
else:
settings.adt_virt = VirtServ(opts.adt_virt)
log_file_name = opts.log_file
if opts.log_level == "error":
setup_logging(logging.ERROR, log_file_name)
elif opts.log_level == "info":
setup_logging(logging.INFO, log_file_name)
elif opts.log_level == "debug":
setup_logging(logging.DEBUG, log_file_name)
else:
setup_logging(DUMP, log_file_name)
exitcode = None
if not settings.tmpdir:
if "TMPDIR" in os.environ:
settings.tmpdir = os.environ["TMPDIR"]
else:
settings.tmpdir = "/tmp"
if not os.path.isdir(settings.tmpdir):
logging.error("Temporary directory is not a directory: %s" %
settings.tmpdir)
panic()
for sdir in settings.scriptsdirs:
if not os.path.isdir(sdir):
logging.error("Scripts directory is not a directory: %s" % sdir)
panic()
if not settings.debian_distros:
settings.debian_distros = defaults.get_distribution()
if not settings.debian_mirrors:
if opts.defaults:
settings.debian_mirrors = defaults.get_mirror()
else:
settings.debian_mirrors = find_default_debian_mirrors()
if not settings.debian_mirrors:
settings.debian_mirrors = defaults.get_mirror()
settings.distro_config = piupartslib.conf.DistroConfig(
DISTRO_CONFIG_FILE, settings.debian_mirrors[0][0])
if settings.keep_sources_list and \
(not settings.basetgz or len(settings.debian_distros) > 1):
logging.error("--keep-sources-list only makes sense with --basetgz "
"and only one distribution")
exitcode = 1
if not args:
logging.error("Need command line arguments: " +
"names of packages or package files")
exitcode = 1
settings.testobjects = args
if exitcode is not None:
sys.exit(exitcode)
return args
def get_chroot():
if settings.adt_virt is None:
return Chroot()
return settings.adt_virt
# Process the packages given in a list
def process_packages(package_list):
# Find the names of packages.
if settings.args_are_package_files:
packages = get_package_names_from_package_files(package_list)
package_files = package_list
else:
packages = package_list
package_files = []
if len(settings.debian_distros) == 1:
chroot = get_chroot()
chroot.create()
chroot_state = {}
chroot_state["tree"] = chroot.save_meta_data()
chroot_state["selections"] = chroot.get_selections()
chroot_state["diversions"] = chroot.get_diversions()
if not settings.no_install_purge_test:
extra_packages = chroot.get_known_packages(settings.extra_old_packages)
if not install_purge_test(chroot, chroot_state,
package_files, packages, extra_packages):
logging.error("FAIL: Installation and purging test.")
panic()
logging.info("PASS: Installation and purging test.")
if not settings.no_upgrade_test:
if not settings.args_are_package_files and not settings.testdebs_repo:
logging.info("Can't test upgrades: -a or --apt option used.")
else:
packages_to_query = unqualify(packages)
packages_to_query.extend(settings.extra_old_packages)
known_packages = chroot.get_known_packages(packages_to_query)
if not known_packages:
logging.info("Can't test upgrade: packages not known by apt-get.")
elif install_upgrade_test(chroot, chroot_state, package_files,
packages, known_packages):
logging.info("PASS: Installation, upgrade and purging tests.")
else:
logging.error("FAIL: Installation, upgrade and purging tests.")
panic()
chroot.remove()
else:
if install_and_upgrade_between_distros(package_files, packages):
logging.info("PASS: Upgrading between Debian distributions.")
else:
logging.error("FAIL: Upgrading between Debian distributions.")
panic()
if settings.adt_virt is not None:
settings.adt_virt.shutdown()
def main():
"""Main program. But you knew that."""
args = parse_command_line()
# check if user has root privileges
if os.getuid():
print 'You need to be root to use piuparts.'
sys.exit(1)
logging.info("-" * 78)
logging.info("To quickly glance what went wrong, scroll down to the bottom of this logfile.")
logging.info("FAQ available at https://wiki.debian.org/piuparts/FAQ")
logging.info("The FAQ also explains how to contact us in case you think piuparts is wrong.")
logging.info("-" * 78)
logging.info("piuparts version %s starting up." % VERSION)
logging.info("Command line arguments: %s" % " ".join(quote_spaces(sys.argv)))
logging.info("Running on: %s %s %s %s %s" % os.uname())
# Make sure debconf does not ask questions and stop everything.
# Packages that don't use debconf will lose.
os.environ["DEBIAN_FRONTEND"] = "noninteractive"
if "DISPLAY" in os.environ:
del os.environ["DISPLAY"]
changes_packages_list = []
regular_packages_list = []
changes_p = re.compile('.*\.changes$')
for arg in args:
if changes_p.match(arg):
package_list = process_changes(arg)
if settings.single_changes_list:
for package in package_list:
regular_packages_list.append(package)
else:
changes_packages_list.append(package_list)
else:
regular_packages_list.append(arg)
if changes_packages_list:
for package_list in changes_packages_list:
process_packages(package_list)
if regular_packages_list:
process_packages(regular_packages_list)
logging.info("PASS: All tests.")
logging.info("piuparts run ends.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print ''
print 'Piuparts interrupted by the user, exiting...'
panic(1)
sys.exit(1)
# vi:set et ts=4 sw=4 :
piuparts-0.64ubuntu1/piuparts.1.txt 0000664 0000000 0000000 00000041564 12536542721 014316 0 ustar piuparts(1)
===========
:doctype: manpage
:revdate: 2015-05-12
NAME
----
piuparts - .deb installation, upgrade, and removal testing suite
SYNOPSIS
--------
*piuparts* ['-apvV'] ['-d' _distro_] ['-i' _filename_] ['-I' _regexp_] ['-l' _logfile_] ['-m' _url_] ['--bindmount' _dir_] [_package_]... [_changes_file_]...
DESCRIPTION
-----------
*piuparts* tests that Debian packages handle installation, upgrading, and removal correctly. It does this by creating a minimal Debian installation in a chroot, and installing, upgrading, and removing packages in that environment, and comparing the state of the directory tree before and after. *piuparts* reports any files that have been added, removed, or modified during this process.
*piuparts* is meant as a quality assurance tool for people who create Debian packages to test them before they upload them to the Debian package
archive.
By default, piuparts can do three different tests:
. A simple install-purge test within one Debian distribution (chosen with the '-d' option, unstable by default). It sets up the chroot with the desired distribution, then installs and purges the packages, and reports problems.
. A simple install-upgrade-purge test within one Debian distribution. This test is like the install-purge test, but install the packages first via *apt-get* and then from the package files given on the command line. If the command line has package names (option '--apt' used), or no tested package is known to *apt-get* (new packages), this test is skipped, otherwise it is performed automatically.
. An upgrade test between Debian releases. This test is enabled by using the '-d' option multiple times and disables the other two tests. It sets up the chroot with the first distribution named, then upgrades it to each successive one, and then remembers the directory tree state at the end. After this, it starts over with the chroot of the first distribution, installs the desired packages (via *apt-get*), and does the successive upgrading (via *apt-get dist-upgrade*). Then, if package files (and not just package names) were given on the command line, it installs them. Finally, it reports problems against the state of the directory tree at the last distribution compared with the state without the packages having been installed. This test can be quite slow to execute.
+
Note that this does not work with experimental, because *apt-get* does not automatically upgrade to packages in experimental. To test a particular package or group of packages in experimental, use the second test.
Command line arguments are the paths to package files (e.g., _piuparts_1.0-1_all.deb_), paths to changes files (e.g., _piuparts_1.0-1_i386.changes_), or names of packages, if the '--apt' option is given.
When processing changes files, by default, all packages in a changes file will be processed together with all individual packages given on the command line. Then each package given on the command line is processed in a single group. If the '--single-changes-list' is used, the packages in all changes files are processed together along with any individual packages that were given on the command line.
*piuparts* outputs to the standard output some log messages to show what is going on. If a log file is used, the messages go there as well.
*piuparts* needs to be run as root.
OPTIONS
-------
Options must come before the other command line arguments.
*-a*, *--apt*::
The package arguments on the command line are to be treated as package names and installed via *apt-get* instead of being names of package files, to be installed via *dpkg -i*.
*--allow-database*::
Allow starting MySQL and PostgreSQL database servers in the chroot for
packages requiring database access in their maintainer scripts.
Do not use this option if there is already a database server running on the
system running piuparts (or piuparts-slave)!
In master-slave setups with multiple slaves running on one host collisions
may occur, these will be detected by 'detect_piuparts_issues' and the
affected packages will be tested again.
*--arch*='arch'::
Create chroot and run tests for (non-default) architecture 'arch'. The default is the output from 'dpkg --print-architecture'.
*-b* 'tarball', *--basetgz*='tarball'::
Use tarball as the contents of the initial chroot, instead of building a new one with debootstrap.
+
The tarball can be created with the '-s' option, or you can use one that *pbuilder* has created (see '-p'). If you create one manually, make sure the root of the chroot is the root of the tarball.
*--bindmount*='dir'::
Bind-mount a directory inside the chroot.
*-d* 'name', *--distribution*='name'::
Which Debian distribution to use: a code name (for example jessie, stretch or sid) or experimental. The default is sid (=unstable).
*-D* 'flavor', *--defaults*='flavor'::
Use default settings suitable for a particular flavor of Debian: either debian or ubuntu. The default is debian.
*--do-not-verify-signatures*::
Do not verify signatures from the Release files when running debootstrap. Also set APT::Get::AllowUnauthenticated accordingly in /etc/apt/apt.conf in the chroots.
*--dpkg-force-confdef*::
Make dpkg use --force-confdef, which lets dpkg always choose the default action when a modified conffile is found. This option will make piuparts ignore errors it was designed to report and therefore should only be used to hide problems in depending packages. 'This option shall normally not be used.' (See #466118.)
*--dpkg-noforce-unsafe-io*::
Prevent running dpkg with --force-unsafe-io. --force-unsafe-io causes dpkg to skip certain file system syncs known to cause substantial performance degradation on some filesystems. Thus, including this option reverts to safe but slower behavior. The --dpkg-noforce-unsafe-io is required for running tests on distributions older than squeeze.
*--no-eatmydata*::
Prevent use of eatmydata. The --no-eatmydata option is required for running tests on squeeze or older distributions.
*--extra-old-packages*='pkg1[,pkg2]...'::
Install additional old packages before upgrading. Allows testing package renames/merges where the old package is no longer available in the new distribution and the new one utilizes Conflicts/Replaces. The argument is a comma separated list of package names and the option can be given multiple times.
For install/purge tests these packages will be installed before the package
that is to be tested.
*-e* 'dirname', *--existing-chroot*='dirname'::
Use the specified directory as source for the new chroot, instead of building
a new one with debootstrap. This is similar to '--basetgz', but the contents
are not archived.
*--distupgrade-to-testdebs*::
Use the "testdebs" repository to override the packages in the distupgrade
target distribution. This allows to test complex upgrade paths before the
packages enter the archive.
*--extra-repo*='deb-line'::
Provide an additional (unparsed) line to be appended to sources.list, e.g.
'deb ' or
'deb file:// ./'
Useful for e.g. backports, security or local repositories that cannot be
handled by '--mirror'. May be repeated to add more than one line.
*-i* 'filename', *--ignore*='filename'::
Add a filename to the list of filenames to be ignored when comparing changes before and after installation. By default, piuparts ignores files that always change during a package installation and uninstallation, such as *dpkg* status files. The filename should be relative to the root of the chroot (e.g., _var/lib/dpkg/status_). This option can be used as many times as necessary.
*-I* 'regexp', *--ignore-regexp*='regexp'::
Add a regular expression pattern to the list of patterns for filenames to be ignored when comparing changes before and after installation. This option can be used as many times as necessary.
*--install-purge-install*::
Purge package after installation and reinstall. All depedencies are installed during purge.
*--install-recommends*::
Enable installation of Recommends.
*--install-remove-install*::
Remove package after installation and reinstall. For testing installation in config-files-remaining state.
*-k*, *--keep-tmpdir*::
Don't remove the temporary directory for the chroot when the program ends.
*-K*, *--keyring*='filename'::
Use FILE as the keyring to use with debootstrap when creating chroots.
*--keep-sources-list*::
Don't modify the chroot's etc/apt/sources.list (only makes sense with '--basetgz').
*--list-installed-files*::
List the files added to the chroot after the installation of the package and after the installation of the package dependencies.
*--lvm-volume*='lvm-volume'::
Use the specified lvm-volume as source for the chroot, instead of building a
new one with debootstrap. This creates a snapshot of the given LVM volume and
mounts it to the chroot path.
*--lvm-snapshot-size*='snapshot-size'::
Use the specified snapshot-size as snapshot size when creating a new LVM
snapshot (default: 1G)
*-l* 'filename', *--log-file*='filename'::
Append log file to _filename_ in addition to the standard output.
*--log-level*='level'::
Display messages from loglevel LEVEL, possible values are: error, info, dump, debug. The default is dump.
*-m* 'url', *--mirror*='url'::
Which Debian mirror to use. The default is the first mirror named in _/etc/apt/sources.list_ or _http://httpredir.debian.org/debian_ if none is found. This option may be used multiple times to use multiple mirrors. Only the first mirror is used with *debootstrap*.
+
The 'components' that are used for a mirror can also be set with this option: a space separated list within the same argument (so you need to quote the entire argument in the shell). If no components are given explicitly, the usual Debian components are used (main, contrib, and non-free). For the mirrors read from _/etc/apt/sources.list_, the components are read from the same place.
+
Note that file: addresses works if the directories are made accessible from within the chroot with '--bindmount'.
*--no-adequate*::
Don't run adequate after installation. The default is to run adequate, provided it is installed.
*--no-diversions*::
Don't check for broken diversions.
*-n*, *--no-ignores*::
Forget all built-in and other ignores that have been set so far. Any '-i' or '-I' arguments that come after this one will be obeyed, but none of the ones that come before.
*-N*, *--no-symlinks*::
Don't check for broken symlinks.
*--fail-if-inadequate*::
Fail on inadequate results from running adequate. The default is to just issue those errors as warnings.
*--fail-on-broken-symlinks*::
Fail on broken symlinks. The default is to just issue those errors as warnings.
*--no-upgrade-test*::
Skip testing upgrade from an existing version in the archive.
*--no-install-purge-test*::
Skip the install and purge test.
*-p, *--pbuilder*::
Use _/var/cache/pbuilder/base.tgz_ as the base tarball. This is a shorthand so that you don't need to use '-b' for it.
*--pedantic-purge-test*::
Be pedantic when checking if a purged package leaves files behind. If this option is not set, files left in _/tmp_ are ignored.")
*--proxy*='URL'::
Use the proxy at URL to access the Debian mirror(s). Takes precedence over
the 'http_proxy' environment variable. Using a local proxy is recommended
because piuparts may use large amounts of bandwidth to repeatedly download
the same files.
*-s* 'filename', *--save*='filename'::
Save the chroot, after it has been set up, as a tarball into _filename_. It can then be used with '-b'.
*-B* 'FILE', *--end-meta*='FILE'::
Load chroot package selection and file meta data from FILE. See the function install_and_upgrade_between_distros() in piuparts.py for defaults. Mostly useful for large scale distro upgrade tests.
*-S* 'FILE', *--save-end-meta*='FILE'::
Save chroot package selection and file meta data in FILE for later use. See the function install_and_upgrade_between_distros() in piuparts.py for defaults. Mostly useful for large scale distro upgrade tests.
*--scriptsdir*='DIR'::
Directory where are custom scripts are placed. By default, this is not set. For more information about this, read README_server.txt
*--schroot*='SCHROOT-NAME'::
Use schroot session named SCHROOT-NAME for the chroot, instead of building a new one with debootstrap.
*--single-changes-list*::
When processing changes files, piuparts will process the packages in each individual changes file seperately. This option will set piuparts to scan the packages of all changes files together along with any individual package files that may have been given on the command line.
*--skip-minimize*::
Allow skip minimize chroot step. This is useful when you want to test several packages with piuparts. You can prepare a tarball already minimized and skip this step in all the tests. This is the default now.
*--minimize*::
Minimize the chroot with debfoster. This used to be the default until #539142 was fixed.
*--skip-cronfiles-test*::
Skip testing the output from the cron files left in the system after remove a package.
*--skip-logrotatefiles-test*::
Skip testing the output from the logrotate files left in the system after remove a package.
*--testdebs-repo*='deb-line'::
Provide an additional line to be appended to sources.list, e.g.
'deb ' or
'deb file:// ./'
If only an URL or local path is given as argument, "deb", "file://", and
"./" will be prepended/appended as needed.
The "testdebs" repository provides the packages to be tested (and some
additional dependencies, if needed, e.g. all packages built from the same
source package as the (binary) package being tested) and can be used for
testing complex installation and upgrade scenarios involving dependencies
that are not yet in the archive. This repository will be available only
for installing the target packages. Dependency resolution will be done by
apt-get. The packages to be tested can be passed as .debs or as package
names (with '--apt').
*-t directory*, *--tmpdir*='directory'::
Use directory as the place where temporary files and directories are created. The default is the environment variable *TMPDIR*, or _/tmp_ if not set.
+
Note: the temporary directory must *not* be mounted with the _nodev_ or _nosuid_ mount option.
*-v*, *--verbose*::
This option no longer has any meaning, but it is still accepted for backwards compatibility.
*-V*, *--version*::
Write out the version number of the program.
*--warn-on-debsums-errors*::
Print a warning rather than failing if debsums reports modified files.
*--warn-on-leftovers-after-purge*::
Print a warning rather than failing if files are left behind after purge.
*--warn-on-others*::
Print a warning rather than failing if files are left behind, modified, or removed by a package that was not given on the command-line.
+
This way, you can basically isolate the purge test to your own packages. If a package that is brought in as a dependency doesn't purge cleanly, the test will not fail because of it (but a warning message will be printed).
+
Behavior with multiple packages given on the command-line could be problematic, particularly if the dependency tree of one package in the list includes another in the list. Therefore, it is recommended to use this option with one package at a time.
EXAMPLES
--------
Assume that you have just built a new version of your Debian package, to be uploaded to Debian unstable. It is in _../foo_1.0-2_i386.deb_ and you would like to know whether it installs and uninstalls properly. Here's what you would do:
----
piuparts ../foo_1.0-2_i386.deb
----
If the package exists in the Debian archive already, the above command also tests that it upgrades properly.
To do the same test, but using a particular mirror, and only the main component, you would do this:
----
piuparts -m 'http://gytha/debian main' ../foo_1.0-2_i386.deb
----
If you want to do the same as above but for your changes files, pass in your changes files when running piuparts, and piuparts will process each package in the changes files as though you had passed all those packages on the command line to piuparts yourself. For example:
----
piuparts ../foo_1.0-2_i386.changes
piuparts -m 'http://gytha/debian main' ../foo_1.0-2_i386.changes
----
If you want to test that a package installs properly in the stable (currently jessie) Debian release, then can be upgraded to the testing (currently stretch) and unstable (sid) versions, and then uninstalled without problems, you would give the following command:
----
piuparts -a -d jessie -d stretch -d sid foo
----
ENVIRONMENT
-----------
*TMPDIR* Location for temporary files and directories. If not set, use _/tmp_. See also the '-t' ('--tmpdir') option.
NOTES
-----
Output of commands run by piuparts is limited to three megabytes. To change this limit, the source code needs to be edited.
Commands exceeding this limit will be aborted.
SEE ALSO
--------
*pbuilder*(1), *debootstrap*(8)
AUTHOR
------
Lars Wirzenius (liw@iki.fi) and others
// vim: set filetype=asciidoc:
piuparts-0.64ubuntu1/master-bin/ 0000775 0000000 0000000 00000000000 12536542664 013604 5 ustar piuparts-0.64ubuntu1/master-bin/master_cleanup.in 0000775 0000000 0000000 00000002175 12452567512 017142 0 ustar #!/bin/sh
set -e
# Copyright © 2012 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# cleanup $HTDOCS/daily.lock
#
# - this should only be run (automatically) on boot
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value HTDOCS global output-directory
LOCKFILE=$HTDOCS/daily.lock
if [ -e $LOCKFILE ]; then
if pgrep -f generate_daily_report || pgrep -f piuparts-report ; then
echo "daily processing is running"
else
rm -f -v $LOCKFILE
fi
fi
piuparts-0.64ubuntu1/master-bin/detect_piuparts_issues.in 0000775 0000000 0000000 00000010726 12517712417 020731 0 ustar #!/bin/sh
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
#
# detect piuparts problems
#
FILE=`mktemp`
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
for subdir in fail bugged affected ; do
test -d $MASTER/$SECTION/$subdir || continue
rgrep -l 'PIUPARTS OUTPUT INCOMPLETE' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -E "tar( \(child\))?: .*.tar.gz: Cannot open: No such file or directory" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "tar: .*: No space left on device" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "tar: Error is not recoverable: exiting now" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "tar: .*: Wrote only .* of .* bytes" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "gzip: stdin: invalid compressed data--crc error" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "ERROR:.*:Temporary directory is not a directory" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "No space left on device" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "E: You don't have enough free space in /var/cache/apt/archives/" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "E: Failed to write temporary StateFile /var/lib/apt/extended_states.tmp" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -E "(chfn|groupadd|useradd): cannot lock /etc/(group|gshadow|passwd|shadow|subuid); try again later." $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -E "(groupadd|useradd): failure while writing changes to /etc/(group|passwd)" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "ERROR: Command failed (status=-7): .* 'apt-cache'" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "^RuntimeError: maximum recursion depth exceeded while calling a Python object" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "^Traceback" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "^OSError:" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "^IndentationError:" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "^SyntaxError:" $MASTER/$SECTION/$subdir >> $FILE
# Python errors from maintainer scripts etc. would be indented by 2 spaces, so don't match here.
rgrep -l -e 'update-binfmts: warning: unable to close /proc/sys/fs/binfmt_misc/register: Invalid argument' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e 'userdel: user .* is currently logged in' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -i -e 'invoke-rc.d: initscript mysql, action "start" failed.' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -i -e 'invoke-rc.d: initscript postgresql, action "start" failed.' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -i -e 'FATAL: could not create shared memory segment: No space left on device' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e 'No database found online on port 5432' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e 'unable to connect to postgresql server' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e 'createuser: could not connect to database postgres: could not connect to server: No such file or directory' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e 'Firebird .* server already running.' $MASTER/$SECTION/$subdir >> $FILE
find $MASTER/$SECTION/$subdir -name '*.log' -size 0 >> $FILE
done
done
if [ -s $FILE ] ; then
echo "piuparts problem detected!"
echo "(By grep'ing for 'tar: .*.tar.gz: Cannot open: No such file or directory'"
echo "and for some python errors and tracebacks in failed logs.)"
echo
echo "Please review the following logfiles/packages."
echo "If it is always the same package failing, it's likely to be an issue in the"
echo "package."
echo
sort -u $FILE | xargs rm -v
echo
echo "----------------------------------------------------------------------"
echo
fi
rm $FILE
piuparts-0.64ubuntu1/master-bin/generate_daily_report.in 0000775 0000000 0000000 00000005713 12517712417 020506 0 ustar #!/bin/sh
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
get_config_value HTDOCS global output-directory
get_config_value URLBASE global urlbase https://piuparts.debian.org
get_config_value PYTHONPATH global PYTHONPATH ''
export PYTHONPATH
LOCKFILE=$HTDOCS/daily.lock
if [ -e $LOCKFILE ]; then
echo "daily.lock exists:"
ls -l $LOCKFILE
exit 1
fi
date > $LOCKFILE
#
# various scripts to detect issues and cleanup
#
OUTPUT=$(mktemp)
for SCRIPT in detect_network_issues detect_piuparts_issues archive_old_logs report_newly_bugged_packages ; do
@sharedir@/piuparts/master/$SCRIPT 2>&1 > $OUTPUT
if [ -s $OUTPUT ] ; then
cat $OUTPUT | mail -s $SCRIPT $LOGNAME
fi
done
rm $OUTPUT
#
# piuparts-report starts here
#
DAILYREPORT=$HTDOCS/dailyreport.txt
>$DAILYREPORT
# Failures of the day it should be, the rest is boring.
FAILURESTAMP=$HTDOCS/last-failure-report.stamp
test -f $FAILURESTAMP || touch -d @0 $FAILURESTAMP # start at the epoch
touch $FAILURESTAMP.new # for the next report
echo "New failures:" >> $DAILYREPORT
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
for DIRECTORY in fail bugged affected untestable ; do
mkdir -p $MASTER/$SECTION/$DIRECTORY
done
find $MASTER/$SECTION/fail $MASTER/$SECTION/bugged $MASTER/$SECTION/affected $MASTER/$SECTION/untestable \
-type f -name '*.log' -newer $FAILURESTAMP -exec ls -1 {} + 2>/dev/null
done | sed s#^$MASTER#$URLBASE# >> $DAILYREPORT
echo "" >> $DAILYREPORT
date >> $DAILYREPORT
@sharedir@/piuparts/master/detect_well_known_errors 2>&1 >> $DAILYREPORT
echo "" >> $DAILYREPORT
date >> $DAILYREPORT
nice \
@sharedir@/piuparts/piuparts-report \
>> $DAILYREPORT 2>&1
date >> $DAILYREPORT
echo "" >> $DAILYREPORT
date >> $DAILYREPORT
echo "Expiring old .html files:" >> $DAILYREPORT
find $HTDOCS -name '* *.html' -mtime +30 -ls -delete >> $DAILYREPORT
expire=$(mktemp)
find $HTDOCS -name '*.html' -mtime +30 | head -n 500 > $expire
if [ -s $expire ]; then
ls -ld $(cat $expire) >> $DAILYREPORT
rm -f $(cat $expire) >> $DAILYREPORT
fi
rm $expire
date >> $DAILYREPORT
cat $DAILYREPORT | mail -s piuparts-report $LOGNAME
mv $FAILURESTAMP.new $FAILURESTAMP
rm -f $LOCKFILE
piuparts-0.64ubuntu1/master-bin/reschedule_oldest_logs.in 0000775 0000000 0000000 00000013022 12517712417 020650 0 ustar #!/bin/sh
# Copyright 2009-2011 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2012 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
#
# reschedule 200 oldest log files, if they are older than 180 days
# reschedule 25 oldest fail log files, if they are older than 30 days
# delete $reschedule-old-count oldest logfiles, if they are scheduled
# for recycling and older than $expire-old-days
# and $expire-old-days > $reschedule-old-days
#
get_config_value EXPIRE_AGE global expire-old-days 0
get_config_value AGE global reschedule-old-days 180
get_config_value COUNT global reschedule-old-count 200
get_config_value EXPIRE_FAIL_AGE global expire-fail-days 0
get_config_value FAIL_AGE global reschedule-fail-days 30
get_config_value FAIL_COUNT global reschedule-fail-count 25
get_config_value AUTO_RESCHEDULE global auto-reschedule yes
RECENT=$(mktemp)
touch -d "2 days ago" "$RECENT"
is_recent()
{
local stamp
stamp="$1"
if [ -f "$stamp" ] && [ "$stamp" -nt "$RECENT" ]; then
return 0
fi
return 1
}
list_logs()
{
__AGE="$1"
__COUNT="$2"
shift 2
find "$@" -name "*.log" -mtime +$__AGE \
| tac \
| xargs --no-run-if-empty -n99999 -s1999999 ls -dt \
| tail -n $__COUNT
}
TOTAL=0
TOTAL_EXPIRED=0
UNSCHEDULE=0
TOTAL_QUEUED=0
LOGS=$(mktemp)
OBSOLETE=$(mktemp)
EXPIRED=$(mktemp)
UNSORTED=$(mktemp)
QUEUED=$(mktemp)
OLDPWD=$(pwd)
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
cd $MASTER/$SECTION
mkdir -p pass fail bugged affected recycle
recycle_was_idle=
find recycle/ -name '*.log' > $QUEUED
if [ ! -s $QUEUED ]; then
recycle_was_idle="empty"
elif [ -f "recycle.stamp" ] && [ "recycle.stamp" -nt "recycle" ]; then
recycle_was_idle="idle"
fi
# Clean up obsolete rescheduling requests
for log in $(find recycle/ -name '*.log' | cut -d"/" -f2) ; do
for dir in pass bugged affected fail ; do
test ! -e "$dir/$log" || continue 2
done
echo "recycle/$log"
done | sort > $OBSOLETE
# Reschedule old logs
>$LOGS
>$EXPIRED
get_config_value RESCHEDULE $SECTION auto-reschedule $AUTO_RESCHEDULE
if [ "$RESCHEDULE" = "yes" ]; then
get_config_value _EXPIRE_AGE $SECTION expire-old-days $EXPIRE_AGE
get_config_value _AGE $SECTION reschedule-old-days $AGE
get_config_value _COUNT $SECTION reschedule-old-count $COUNT
get_config_value _EXPIRE_FAIL_AGE $SECTION expire-fail-days $EXPIRE_FAIL_AGE
get_config_value _FAIL_AGE $SECTION reschedule-fail-days $FAIL_AGE
get_config_value _FAIL_COUNT $SECTION reschedule-fail-count $FAIL_COUNT
# FIXME: we ignore bugged here - ptyhon-bts is really the way to go
>$UNSORTED
if [ "$_EXPIRE_AGE" -gt "$_AGE" ]; then
if [ -n "$recycle_was_idle" ]; then
list_logs $_EXPIRE_AGE $_COUNT pass fail affected >> $UNSORTED
fi
fi
if [ "$_EXPIRE_FAIL_AGE" -gt "$_FAIL_AGE" ]; then
list_logs $_EXPIRE_FAIL_AGE $_FAIL_COUNT fail affected >> $UNSORTED
fi
for log in $(sort -u $UNSORTED) ; do
# the log needs to be scheduled for recycling before it gets expired
test -f "recycle/${log#*/}" && echo "$log"
done > $EXPIRED
>$UNSORTED
if is_recent idle.stamp ; then
list_logs $_AGE $_COUNT pass fail affected >> $UNSORTED
fi
list_logs $_FAIL_AGE $_FAIL_COUNT fail affected >> $UNSORTED
for log in $(sort -u $UNSORTED) ; do
# skip if already scheduled
test -f "recycle/${log#*/}" || echo "$log"
done > $LOGS
fi
find recycle/ -name '*.log' > $QUEUED
if [ -s $LOGS ] || [ -s $OBSOLETE ] || [ -s $EXPIRED ] || [ -s $QUEUED ] ; then
RCOUNT=$(wc -l $LOGS | awk '{ print $1 }')
TOTAL=$(($TOTAL + $RCOUNT))
ECOUNT=$(wc -l $EXPIRED | awk '{ print $1 }')
TOTAL_EXPIRED=$(($TOTAL_EXPIRED + $ECOUNT))
UCOUNT=$(wc -l $OBSOLETE | awk '{ print $1 }')
UNSCHEDULE=$(($UNSCHEDULE + $UCOUNT))
echo "$SECTION: $RCOUNT rescheduled, $ECOUNT expired, $UCOUNT obsolete${recycle_was_idle:+ (recycle-was-${recycle_was_idle})}"
if [ -s $LOGS ]; then
ls -dtl $(cat $LOGS)
ln -f $(cat $LOGS) recycle/
fi
if [ -s $EXPIRED ]; then
ls -dtl $(cat $EXPIRED)
rm -fv $(cat $EXPIRED)
fi
if [ -s $OBSOLETE ]; then
rm -fv $(cat $OBSOLETE)
fi
find recycle/ -name '*.log' > $QUEUED
NUM_QUEUED=$(wc -l < $QUEUED)
TOTAL_QUEUED=$(($TOTAL_QUEUED + $NUM_QUEUED))
echo "queued: $NUM_QUEUED"
echo
echo "#########################################################"
echo
fi
cd $OLDPWD
done
rm $RECENT
rm $LOGS
rm $OBSOLETE
rm $EXPIRED
rm $UNSORTED
rm $QUEUED
if [ "$TOTAL" -gt "0" ]; then
echo "Rescheduled $TOTAL logs."
fi
if [ "$TOTAL_EXPIRED" -gt "0" ]; then
echo "Deleted $TOTAL_EXPIRED expired logs."
fi
if [ "$UNSCHEDULE" -gt "0" ]; then
echo "Cancelled $UNSCHEDULE outdated rescheduling requests."
fi
if [ "$TOTAL_QUEUED" -gt "0" ]; then
echo "Queued logs: $TOTAL_QUEUED"
fi
piuparts-0.64ubuntu1/master-bin/report_newly_bugged_packages.in 0000775 0000000 0000000 00000002625 12452567512 022044 0 ustar #!/bin/sh
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
get_config_value PYTHONPATH global PYTHONPATH ''
get_config_value DEBEMAIL global bts-from ''
export PYTHONPATH
OLDPWD=$(pwd)
OUTPUT=$(mktemp)
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
cd $MASTER/$SECTION
get_config_value DISTROS $SECTION upgrade-test-distros ''
distro=${DISTROS##* }
distro=${distro%-proposed}
timeout 60m @sharedir@/piuparts/piuparts-analyze $distro 2>&1 > $OUTPUT
if [ -s $OUTPUT ]; then
echo $SECTION
cat $OUTPUT
echo
fi
cd "$OLDPWD"
done
rm $OUTPUT
piuparts-0.64ubuntu1/master-bin/detect_archive_issues.in 0000775 0000000 0000000 00000005161 12517712417 020500 0 ustar #!/bin/sh
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
get_config_value URLBASE global urlbase https://piuparts.debian.org
get_config_value DAYS global reschedule-untestable-days 7
#
# detect packages which are/were untestable due to archive issue and mark them as such
#
LOGS=`mktemp`
URLS=`mktemp`
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
mkdir -p $MASTER/$SECTION/fail/ $MASTER/$SECTION/untestable/
find $MASTER/$SECTION/fail -name '*.log' -mtime +1 | xargs -r \
grep -l -E "E: Broken packages|E: Unable to correct problems, you have held broken packages|E: Error, pkgProblemResolver::Resolve generated breaks" 2>/dev/null > $LOGS
if [ -s $LOGS ]; then
for package_log in $(cat $LOGS)
do
mv $package_log $MASTER/$SECTION/untestable/
done
sed "s#$MASTER/$SECTION/fail#$URLBASE/$SECTION/untestable#" $LOGS >> $URLS
fi
done
if [ -s $URLS ]; then
date >> $MASTER/archive_issues.txt
cat $URLS >> $MASTER/archive_issues.txt
echo "Broken packages detected!"
echo "(By grep'ing for"
echo " 'E: Broken packages',"
echo " 'E: Unable to correct problems, you have held broken packages',"
echo " 'E: Error, pkgProblemResolver::Resolve generated breaks'"
echo "in failed logs.)"
echo
echo 'The following packages have been moved to $section/untestable and will be'
echo "tested again in $DAYS days."
echo
echo "Broken packages are usually a temporary problem in the archive and are"
echo "caught by other tools like britney or https://qa.debian.org/dose/debcheck.html"
echo
echo "If it is always the same package failing, it's likely to be an issue in the"
echo "package."
echo
grep -f $URLS $MASTER/archive_issues.txt | sort | uniq -c | sort -rn
echo
fi
rm $LOGS $URLS
piuparts-0.64ubuntu1/master-bin/prepare_backup.in 0000775 0000000 0000000 00000003315 12517712417 017116 0 ustar #!/bin/sh
set -e
# Copyright 2009,2014 Holger Levsen (holger@layer-acht.org)
# Copyright © 2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# backup statistiscs files to a single directory for DSA to backup
# piuparts.d.o's state is not backupped
# (currently it takes one month to run a full piuparts test on a suite
# which produces a gigabyte of logfiles to be saved, for basically
# not much value)
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value SECTIONS global sections
get_config_value MASTER global master-directory
get_config_value HTDOCS global output-directory
get_config_value BACKUPDIR global backup-directory ''
copy_to_backupdir() {
if [ -f $MASTER/$1 ]; then
cp $MASTER/$1 $BACKUPDIR/$1
else
echo "Warning: $MASTER/$1 does not exist."
fi
}
test -n "$BACKUPDIR" || exit 0
copy_to_backupdir archive_issues.txt
copy_to_backupdir bts_stats.txt
for SECTION in $SECTIONS ; do
mkdir -p $BACKUPDIR/$SECTION
copy_to_backupdir $SECTION/submissions.txt
copy_to_backupdir $SECTION/counts.txt
done
piuparts-0.64ubuntu1/master-bin/report_stale_reserved_packages.in 0000775 0000000 0000000 00000002715 12452567512 022400 0 ustar #!/bin/sh
# Copyright 2009,2010 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2012 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
#
# find packages which have been reserved for more than one day and unschedule them
#
DAYS=1
LOGS=`mktemp`
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION/reserved || continue
find $MASTER/$SECTION/reserved/ -mtime +$DAYS -name "*.log" 2>/dev/null >> $LOGS
done
if [ -s $LOGS ] ; then
echo "Stale reserved packages detected, which have been reserved more then $DAYS days ago!"
echo "These packages have been unscheduled."
echo
for package_log in $(cat $LOGS) ; do
rm -fv $package_log
done
fi
rm $LOGS
piuparts-0.64ubuntu1/master-bin/archive_old_logs.in 0000775 0000000 0000000 00000004255 12452567512 017444 0 ustar #!/bin/sh
# Copyright 2009-2011 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
#
# archive old log files
#
TOTAL=0
OLDPWD=$(pwd)
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
cd $MASTER/$SECTION
mkdir -p pass bugged affected fail
mkdir -p archive/pass archive/bugged archive/affected archive/fail
test -f archive/stamp || touch -d @0 archive/stamp # start at the epoch
touch -d yesterday archive/stamp.new # look back one more day the next time we will be run
OUTPUT=""
# loop through all packages logs
for PACKAGE in $(find pass/ fail/ bugged/ affected/ -name '*.log' -newer archive/stamp | cut -d"_" -f1 | cut -d"/" -f2 | sort -u) ; do
# all logs except the last one (|sed '$d' deletes the last line)
OLDLOGS=$( ls -tr1 --color=none bugged/${PACKAGE}_*.log affected/${PACKAGE}_*.log fail/${PACKAGE}_*.log pass/${PACKAGE}_*.log 2>/dev/null|sed '$d' )
if [ ! -z "$OLDLOGS" ] ; then
if [ -z "$OUTPUT" ] ; then
OUTPUT="yes"
echo $SECTION
fi
for LOG in $OLDLOGS ; do
TOTAL=$(($TOTAL + 1))
mv -v $LOG archive/$(echo $LOG|cut -d"/" -f1)/
done
fi
done
find archive/ -name '*.log' | xargs -r xz -f
if [ -n "$OUTPUT" ] ; then
echo
echo
fi
mv archive/stamp.new archive/stamp
cd "$OLDPWD"
done
if [ "$TOTAL" -gt "0" ]; then
echo "Archived $TOTAL old logfiles."
fi
piuparts-0.64ubuntu1/master-bin/report_untestable_packages.in 0000775 0000000 0000000 00000003042 12452567512 021531 0 ustar #!/bin/sh
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2012 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
get_config_value DAYS global reschedule-untestable-days 7
#
# find packages which have been in untestable for more than $DAYS days and reschedule them for testing
#
LOGS=`mktemp`
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION/untestable || continue
find $MASTER/$SECTION/untestable/ -mtime +$DAYS -name "*.log" 2>/dev/null >> $LOGS
done
if [ -s $LOGS ] ; then
echo "Untestable packages detected, which have been tested more than $DAYS days ago!"
echo "These packages have been rescheduled for piuparts testing."
echo
for package_log in $(cat $LOGS) ; do
rm -fv $package_log
done
fi
rm $LOGS
piuparts-0.64ubuntu1/master-bin/gather_bts_stats.in 0000775 0000000 0000000 00000004607 12452567512 017502 0 ustar #!/bin/bash
set -e
# Copyright 2013,2014 Holger Levsen (holger@layer-acht.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
BTS_STATS="$MASTER/bts_stats.txt"
# exit if master-directory doesn't exist or if devscripts package is not installed
test -n "$MASTER" || $(which bts) || exit 0
# "bts select" needs libsoap-lite-perl too
dpkg -l libsoap-lite-perl >/dev/null 2>&1 || exit 0
# only run once a day
TODAY=$(date +%Y%m%d)
if $(grep -q ^$TODAY $BTS_STATS 2>/dev/null) ; then
exit 0
fi
# query bts
RC="severity:serious severity:grave severity:critical"
OTHER="severity:wishlist severity:minor severity:normal severity:important"
DONE_RC=$(bts select usertag:piuparts users:debian-qa@lists.debian.org status:done archive:both $RC 2>/dev/null|wc -l)
OPEN_RC=$(bts select usertag:piuparts users:debian-qa@lists.debian.org status:open status:forwarded $RC 2>/dev/null|wc -l)
DONE_OTHER=$(bts select usertag:piuparts users:debian-qa@lists.debian.org status:done archive:both $OTHER 2>/dev/null|wc -l)
OPEN_OTHER=$(bts select usertag:piuparts users:debian-qa@lists.debian.org status:open status:forwarded $OTHER 2>/dev/null|wc -l)
# test if both values are integers
if ! ( [[ $DONE_RC =~ ^-?[0-9]+$ ]] && [[ $OPEN_RC =~ ^-?[0-9]+$ ]] && [[ $DONE_OTHER =~ ^-?[0-9]+$ ]] && [[ $OPEN_OTHER =~ ^-?[0-9]+$ ]] ) ; then
echo "Non-integer value detected, exiting."
echo "DONE_RC: $DONE_RC OPEN_RC: $OPEN_RC"
echo "DONE_OTHER: $DONE_OTHER OPEN_OTHER: $OPEN_OTHER"
exit 1
fi
# init file if needed
if [ ! -f $BTS_STATS ] ; then
echo "date, non-RC done, non-RC open, RC done, RC open" > $BTS_STATS
fi
# finally, write stats
echo "$TODAY, $DONE_OTHER, $OPEN_OTHER, $DONE_RC, $OPEN_RC" >> $BTS_STATS
piuparts-0.64ubuntu1/master-bin/detect_well_known_errors.py 0000775 0000000 0000000 00000015071 12525654513 021263 0 ustar #!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright 2013 David Steele (dsteele@gmail.com)
# Copyright © 2014 Andreas Beckmann (anbe@debian.org)
#
# This file is part of Piuparts
#
# Piuparts is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# Piuparts is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see .
import ConfigParser
import os
import sys
import time
import logging
import argparse
import piupartslib
from piupartslib.conf import MissingSection
from piupartslib.dwke import *
CONFIG_FILE = "/etc/piuparts/piuparts.conf"
KPR_DIRS = ('pass', 'bugged', 'affected', 'fail')
class WKE_Config(piupartslib.conf.Config):
"""Configuration parameters for Well Known Errors"""
def __init__(self):
self.section = 'global'
piupartslib.conf.Config.__init__(self, self.section,
{
"sections": "report",
"master-directory": ".",
"known-problem-directory": "@sharedir@/piuparts/known_problems",
}, "")
def setup_logging(log_level):
logger = logging.getLogger()
logger.setLevel(log_level)
handler = logging.StreamHandler(sys.stdout)
logger.addHandler(handler)
def write_file(filename, contents):
with file(filename, "w") as f:
f.write(contents)
def mtime(path):
return os.path.getmtime(path)
def clean_cache_files(logdict, cachedict, recheck=False, recheck_failed=False,
skipnewer=False):
"""Delete files in cachedict if the corresponding logdict file is missing
or newer"""
count = 0
for pkgspec in cachedict:
try:
if pkgspec not in logdict \
or (mtime(logdict[pkgspec]) > mtime(cachedict[pkgspec]) and not skipnewer)\
or get_where(logdict[pkgspec]) != get_where(cachedict[pkgspec])\
or recheck\
or (recheck_failed and not get_where(cachedict[pkgspec]) in ['pass']):
os.remove(cachedict[pkgspec])
count = count + 1
except (IOError, OSError):
# logfile may have disappeared
pass
return count
def make_kprs(logdict, kprdict, problem_list):
"""Create kpr files, as necessary, so every log file has one
kpr entries are e.g.
fail/xorg-docs_1:1.6-1.log broken_symlinks_error.conf"""
needs_kpr = set(logdict.keys()).difference(set(kprdict.keys()))
for pkg_spec in needs_kpr:
logpath = logdict[pkg_spec]
try:
lb = open(logpath, 'r')
logbody = lb.read()
lb.close()
where = get_where(logpath)
kprs = ""
for problem in problem_list:
if problem.has_problem(logbody, where):
kprs += "%s/%s.log %s\n" % (where, pkg_spec, problem.name)
if not where in ['pass'] and not len(kprs):
kprs += "%s/%s.log %s\n" % (where, pkg_spec, "unclassified_failures.conf")
write_file(get_kpr_path(logpath), kprs)
except IOError:
logging.error("File error processing %s" % logpath)
return len(needs_kpr)
def process_section(section, config, problem_list,
recheck=False, recheck_failed=False, pkgsdb=None):
""" Update .bug and .kpr files for logs in this section """
sectiondir = os.path.join(config['master-directory'], section)
workdirs = [os.path.join(sectiondir, x) for x in KPR_DIRS]
if not os.access(sectiondir, os.F_OK):
raise MissingSection("", section)
[os.mkdir(x) for x in workdirs if not os.path.exists(x)]
logdict = get_file_dict(workdirs, LOG_EXT)
kprdict = get_file_dict(workdirs, KPR_EXT)
bugdict = get_file_dict(workdirs, BUG_EXT)
del_cnt = clean_cache_files(logdict, kprdict, recheck, recheck_failed)
clean_cache_files(logdict, bugdict, skipnewer=True)
kprdict = get_file_dict(workdirs, KPR_EXT)
add_cnt = make_kprs(logdict, kprdict, problem_list)
failures = FailureManager(logdict)
return (del_cnt, add_cnt, failures)
def detect_well_known_errors(sections, config, problem_list, recheck, recheck_failed):
for section in sections:
try:
logging.info(time.strftime("%a %b %2d %H:%M:%S %Z %Y", time.localtime()))
logging.info("%s:" % section)
(del_cnt, add_cnt, failures) = \
process_section(section, config, problem_list,
recheck, recheck_failed)
logging.info("parsed logfiles: %d removed, %d added" % (del_cnt, add_cnt))
for prob in problem_list:
pcount = len(failures.filtered(prob.name))
if pcount:
logging.info("%7d %s" % (pcount, prob.name))
except MissingSection:
pass
logging.info(time.strftime("%a %b %2d %H:%M:%S %Z %Y", time.localtime()))
if __name__ == '__main__':
setup_logging(logging.DEBUG)
parser = argparse.ArgumentParser(
description="Detect well known errors",
epilog="""
This script processes all log files against defined "known_problem" files,
caching the problems found, by package, into ".kpr" files.
""")
parser.add_argument('sections', nargs='*', metavar='SECTION',
help="limit processing to the listed SECTION(s)")
parser.add_argument('--recheck', dest='recheck', action='store_true',
help="recheck all log files (delete cache)")
parser.add_argument('--recheck-failed', dest='recheck_failed',
action='store_true',
help="recheck failed log files (delete cache)")
args = parser.parse_args()
conf = WKE_Config()
conf.read(CONFIG_FILE)
sections = args.sections
if not sections:
sections = conf['sections'].split()
problem_list = create_problem_list(conf['known-problem-directory'])
detect_well_known_errors(sections, conf, problem_list, args.recheck,
args.recheck_failed)
# vi:set et ts=4 sw=4 :
piuparts-0.64ubuntu1/master-bin/detect_network_issues.in 0000775 0000000 0000000 00000006553 12517712417 020556 0 ustar #!/bin/sh
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
#
# detect network/mirror problems
#
FILE=`mktemp`
for SECTION in $SECTIONS ; do
test -d $MASTER/$SECTION || continue
for subdir in fail bugged affected ; do
test -d $MASTER/$SECTION/$subdir || continue
rgrep -l "Cannot initiate the connection to" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "Hash Sum mismatch" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "Failed to fetch.*Could not resolve" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "Failed to fetch.*Something wicked happened resolving" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "Failed to fetch.*Unable to connect to" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "E: Method http has died unexpectedly" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "Some index files failed to download, they have been ignored, or old ones used instead." $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "Some index files failed to download. They have been ignored, or old ones used instead." $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "W: GPG error: .* Release: The following signatures were invalid: BADSIG" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -e "E: Version '.*' for '.*' was not found" $MASTER/$SECTION/$subdir >> $FILE
rgrep -l 'E: Method file has died unexpectedly!' $MASTER/$SECTION/$subdir >> $FILE
rgrep -l "E: Sub-process rred received a segmentation fault." $MASTER/$SECTION/$subdir >> $FILE
rgrep -l -E "ERROR: Command failed \(status=-7\):.*'apt-get', 'update'" $MASTER/$SECTION/$subdir >> $FILE
# modified changelogs are usually caused by mirror pushes during the piuparts test
rgrep -l -E ' /usr/share/doc/(.*)/changelog.*owned by: \1' $MASTER/$SECTION/$subdir >> $FILE
done
done
if [ -s $FILE ] ; then
echo "Network problems on detected!"
echo "(By grep'ing for"
echo " 'Cannot initiate the connection to',"
echo " 'Failed to fetch',"
echo " 'Some index files failed to download',"
echo " 'Hash Sum mismatch',"
echo " 'The following signatures were invalid'"
echo "in failed logs.)"
echo "Test failures due to modified /usr/share/doc/*/changelog.*"
echo "are caused by mirror updates during the test."
echo
echo "The following logfiles have been deleted:"
echo
echo "----------------------------------------------------------------------"
echo
for LOG in $(sort -u $FILE) ; do
rm -v $LOG
done
echo
fi
rm $FILE
piuparts-0.64ubuntu1/master-bin/reclassify_bugged.in 0000775 0000000 0000000 00000002441 12452567512 017615 0 ustar #!/bin/sh
set -e
# Copyright © 2012 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value SECTIONS global sections
OLDPWD=$(pwd)
for SECTION in $SECTIONS ; do
get_config_value KEEP_BUGGED $SECTION keep-bugged no
if [ "$KEEP_BUGGED" = "no" ] && [ -d $MASTER/$SECTION/fail ] && [ -d $MASTER/$SECTION/bugged ]; then
cd $MASTER/$SECTION
mv bugged/*.log bugged/*.bug fail/ 2>/dev/null
mv affected/*.log affected/*.bug fail/ 2>/dev/null
cd "$OLDPWD"
fi
done
@sharedir@/piuparts/master/report_newly_bugged_packages
piuparts-0.64ubuntu1/piuparts-slave.py 0000664 0000000 0000000 00000107311 12536542721 015071 0 ustar #!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Copyright 2005 Lars Wirzenius (liw@iki.fi)
# Copyright © 2011-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""Distributed piuparts processing, slave program
Lars Wirzenius
"""
import os
import sys
import stat
import time
import logging
from signal import alarm, signal, SIGALRM, SIGINT, SIGKILL, SIGHUP
import subprocess
import fcntl
import random
import ConfigParser
import apt_pkg
import piupartslib.conf
import piupartslib.packagesdb
from piupartslib.conf import MissingSection
apt_pkg.init_system()
CONFIG_FILE = "/etc/piuparts/piuparts.conf"
DISTRO_CONFIG_FILE = "/etc/piuparts/distros.conf"
MAX_WAIT_TEST_RUN = 45 * 60
interrupted = False
old_sigint_handler = None
got_sighup = False
def setup_logging(log_level, log_file_name):
logger = logging.getLogger()
logger.setLevel(log_level)
formatter = logging.Formatter(fmt="%(asctime)s %(message)s",
datefmt="%H:%M:%S")
handler = logging.StreamHandler(sys.stderr)
handler.setFormatter(formatter)
logger.addHandler(handler)
if log_file_name:
handler = logging.FileHandler(log_file_name)
logger.addHandler(handler)
class Config(piupartslib.conf.Config):
def __init__(self, section="slave", defaults_section=None):
self.section = section
piupartslib.conf.Config.__init__(self, section,
{
"sections": "slave",
"basetgz-sections": "",
"idle-sleep": 300,
"max-tgz-age": 2592000,
"min-tgz-retry-delay": 21600,
"master-host": None,
"master-user": None,
"master-command": None,
"proxy": None,
"mirror": None,
"piuparts-command": "sudo piuparts",
"piuparts-flags": "",
"tmpdir": None,
"distro": None,
"area": None,
"components": None,
"chroot-tgz": None,
"upgrade-test-distros": None,
"basetgz-directory": ".",
"max-reserved": 1,
"debug": "no",
"keep-sources-list": "no",
"arch": None,
"precedence": "1",
"slave-load-max": None,
},
defaults_section=defaults_section)
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
def sigint_handler(signum, frame):
global interrupted
interrupted = True
print '\nSlave interrupted by the user, waiting for the current test to finish.'
print 'Press Ctrl-C again to abort now.'
signal(SIGINT, old_sigint_handler)
def sighup_handler(signum, frame):
global got_sighup
got_sighup = True
print 'SIGHUP: Will flush finished logs.'
class MasterIsBusy(Exception):
def __init__(self):
self.args = "Master is busy, retry later",
class MasterNotOK(Exception):
def __init__(self):
self.args = "Master did not respond with 'ok'",
class MasterDidNotGreet(Exception):
def __init__(self):
self.args = "Master did not start with 'hello'",
class MasterCommunicationFailed(Exception):
def __init__(self):
self.args = "Communication with master failed",
class MasterIsCrazy(Exception):
def __init__(self):
self.args = "Master said something unexpected",
class MasterCantRecycle(Exception):
def __init__(self):
self.args = "Master has nothing to recycle",
class Slave:
def __init__(self):
self._to_master = None
self._from_master = None
self._master_host = None
self._master_user = None
self._master_command = None
self._section = None
def _readline(self):
try:
line = self._from_master.readline()
except IOError:
raise MasterCommunicationFailed()
logging.debug("<< " + line.rstrip())
return line
def _writeline(self, *words):
line = " ".join(words)
logging.debug(">> " + line)
try:
self._to_master.write(line + "\n")
self._to_master.flush()
except IOError:
raise MasterCommunicationFailed()
def set_master_host(self, host):
logging.debug("Setting master host to %s" % host)
if self._master_host != host:
self.close()
self._master_host = host
def set_master_user(self, user):
logging.debug("Setting master user to %s" % user)
if self._master_user != user:
self.close()
self._master_user = user
def set_master_command(self, cmd):
logging.debug("Setting master command to %s" % cmd)
if self._master_command != cmd:
self.close()
self._master_command = cmd
def set_section(self, section):
logging.debug("Setting section to %s" % section)
self._section = section
def connect_to_master(self):
if not self._is_connected():
self._initial_connect()
self._select_section()
def _is_connected(self):
return self._to_master and self._from_master
def _initial_connect(self):
logging.info("Connecting to %s" % self._master_host)
ssh_command = ["ssh", "-x"]
if self._master_user:
ssh_command.extend(["-l", self._master_user])
ssh_command.append(self._master_host)
ssh_command.append(self._master_command or "command-is-set-in-authorized_keys")
p = subprocess.Popen(ssh_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
self._to_master = p.stdin
self._from_master = p.stdout
line = self._readline()
if line != "hello\n":
raise MasterDidNotGreet()
def _select_section(self):
self._writeline("section", self._section)
line = self._readline()
if line == "busy\n":
raise MasterIsBusy()
elif line != "ok\n":
raise MasterNotOK()
logging.debug("Connected to master")
def close(self):
if self._from_master is None and self._to_master is None:
return
logging.debug("Closing connection to master")
if self._from_master is not None:
self._from_master.close()
if self._to_master is not None:
self._to_master.close()
self._from_master = self._to_master = None
logging.info("Connection to master closed")
def send_log(self, section, pass_or_fail, filename):
logging.info("Sending log file %s/%s" % (section, filename))
basename = os.path.basename(filename)
package, rest = basename.split("_", 1)
version = rest[:-len(".log")]
self._writeline(pass_or_fail, package, version)
f = file(filename, "r")
for line in f:
if line.endswith("\n"):
line = line[:-1]
self._writeline(" " + line)
f.close()
self._writeline(".")
line = self._readline()
if line != "ok\n":
raise MasterNotOK()
def get_status(self, section):
self._writeline("status")
line = self._readline()
words = line.split()
if words and words[0] == "ok":
logging.info("Master " + section + " status: " + " ".join(words[1:]))
else:
raise MasterIsCrazy()
def enable_recycling(self):
self._writeline("recycle")
line = self._readline()
words = line.split()
if line != "ok\n":
raise MasterCantRecycle()
def get_idle(self):
self._writeline("idle")
line = self._readline()
words = line.split()
if words and words[0] == "ok" and len(words) == 2:
return int(words[1])
else:
raise MasterIsCrazy()
def reserve(self):
self._writeline("reserve")
line = self._readline()
words = line.split()
if words and words[0] == "ok":
logging.info("Reserved for us: %s %s" % (words[1], words[2]))
self.remember_reservation(words[1], words[2])
return True
elif words and words[0] == "error":
logging.info("Master didn't reserve anything (more) for us")
return False
else:
raise MasterIsCrazy()
def unreserve(self, filename):
basename = os.path.basename(filename)
package, rest = basename.split("_", 1)
version = rest[:-len(".log")]
logging.info("Unreserve: %s %s" % (package, version))
self._writeline("unreserve", package, version)
line = self._readline()
if line != "ok\n":
raise MasterNotOK()
def _reserved_filename(self, name, version):
return os.path.join("reserved", "%s_%s.log" % (name, version))
def remember_reservation(self, name, version):
create_file(self._reserved_filename(name, version), "")
def get_reserved(self):
vlist = []
for basename in os.listdir("reserved"):
if "_" in basename and basename.endswith(".log"):
name, version = basename[:-len(".log")].split("_", 1)
vlist.append((name, version))
return vlist
def forget_reserved(self, name, version):
try:
os.remove(self._reserved_filename(name, version))
except os.error:
pass
class Section:
def __init__(self, section, slave=None):
self._config = Config(section=section, defaults_section="global")
self._config.read(CONFIG_FILE)
self._distro_config = piupartslib.conf.DistroConfig(
DISTRO_CONFIG_FILE, self._config["mirror"])
self._error_wait_until = 0
self._idle_wait_until = 0
self._recycle_wait_until = 0
self._tarball_wait_until = 0
self._slave_directory = os.path.abspath(section)
if not os.path.exists(self._slave_directory):
os.makedirs(self._slave_directory)
if self._config["debug"] in ["yes", "true"]:
self._logger = logging.getLogger()
self._logger.setLevel(logging.DEBUG)
if int(self._config["max-reserved"]) > 0:
self._check_tarball()
for rdir in ["new", "pass", "fail", "untestable", "reserved"]:
rdir = os.path.join(self._slave_directory, rdir)
if not os.path.exists(rdir):
os.mkdir(rdir)
self._slave = slave or Slave()
def _throttle_if_overloaded(self):
global interrupted
if interrupted or got_sighup:
return
if self._config["slave-load-max"] is None:
return
load_max = float(self._config["slave-load-max"])
if load_max < 1.0:
return
if os.getloadavg()[0] <= load_max:
return
load_resume = max(load_max - 1.0, 0.9)
secs = random.randrange(30, 90)
self._slave.close()
while True:
load = os.getloadavg()[0]
if load <= load_resume:
break
logging.info("Sleeping due to high load (%.2f)" % load)
try:
time.sleep(secs)
except KeyboardInterrupt:
interrupted = True
if interrupted or got_sighup:
break
if secs < 300:
secs += random.randrange(30, 90)
def _connect_to_master(self, recycle=False):
self._slave.set_master_host(self._config["master-host"])
self._slave.set_master_user(self._config["master-user"])
self._slave.set_master_command(self._config["master-command"])
self._slave.set_section(self._config.section)
self._slave.connect_to_master()
if recycle:
self._slave.enable_recycling()
def _get_tarball(self):
basetgz = self._config["chroot-tgz"] or \
self._distro_config.get_basetgz(self._config.get_start_distro(),
self._config.get_arch())
return os.path.join(self._config["basetgz-directory"], basetgz)
def _check_tarball(self):
if int(self._config["max-tgz-age"]) < 0:
return
oldcwd = os.getcwd()
os.chdir(self._slave_directory)
tgz = self._get_tarball()
max_tgz_age = int(self._config["max-tgz-age"])
min_tgz_retry_delay = int(self._config["min-tgz-retry-delay"])
ttl = 0
needs_update = not os.path.exists(tgz)
if not needs_update and max_tgz_age > 0:
# tgz exists and age is limited, so check age
now = time.time()
age = now - os.path.getmtime(tgz)
ttl = max_tgz_age - age
logging.info("Check-replace %s: age=%d vs. max=%d" % (tgz, age, max_tgz_age))
if ttl < 0:
if os.path.exists(tgz + ".log"):
age = now - os.path.getmtime(tgz + ".log")
ttl = min_tgz_retry_delay - age
logging.info("Limit-replace %s: last-retry=%d vs. min=%d" % (tgz, age, min_tgz_retry_delay))
if ttl < 0:
needs_update = True
logging.info("%s too old. Forcing re-creation" % tgz)
if needs_update:
create_chroot(self._config, tgz, self._config.get_start_distro())
ttl = min_tgz_retry_delay
self._tarball_wait_until = time.time() + ttl
os.chdir(oldcwd)
def _count_submittable_logs(self):
files = 0
subdirs = ["pass", "fail", "untestable"]
if interrupted:
subdirs += ["reserved", "new"]
for logdir in subdirs:
for basename in os.listdir(os.path.join(self._slave_directory, logdir)):
if basename.endswith(".log"):
files += 1
return files
def precedence(self):
return int(self._config["precedence"])
def sleep_until(self, recycle=False):
if recycle:
return max(self._error_wait_until, self._recycle_wait_until)
return max(self._error_wait_until, self._idle_wait_until)
def run(self, do_processing=True, recycle=False):
if time.time() < self.sleep_until(recycle=recycle):
return 0
self._throttle_if_overloaded()
self._config = Config(section=self._config.section, defaults_section="global")
try:
self._config.read(CONFIG_FILE)
except MissingSection:
logging.info("unknown section " + self._config.section)
self._error_wait_until = time.time() + 3600
return 0
self._distro_config = piupartslib.conf.DistroConfig(
DISTRO_CONFIG_FILE, self._config["mirror"])
if interrupted or got_sighup:
do_processing = False
if do_processing and time.time() > self._tarball_wait_until:
self._check_tarball()
if self._config.get_distro() == "None":
# section is for tarball creation only
self._idle_wait_until = self._tarball_wait_until + 60
self._recycle_wait_until = self._tarball_wait_until + 3600
return 0
if interrupted or got_sighup:
do_processing = False
if not do_processing and self._count_submittable_logs() == 0:
return 0
logging.info("-------------------------------------------")
action = "Running"
if recycle:
action = "Recycling"
if not do_processing:
action = "Flushing"
logging.info("%s section %s (precedence=%d)"
% (action, self._config.section, self.precedence()))
if int(self._config["max-reserved"]) == 0:
logging.info("disabled")
self._error_wait_until = time.time() + 12 * 3600
return 0
if not self._config.get_distro() and not self._config.get_distros():
logging.error("neither 'distro' nor 'upgrade-test-distros' configured")
self._error_wait_until = time.time() + 3600
return 0
with open(os.path.join(self._slave_directory, "slave.lock"), "we") as lock:
oldcwd = os.getcwd()
os.chdir(self._slave_directory)
try:
fcntl.flock(lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
logging.info("busy")
self._error_wait_until = time.time() + 900
else:
if self._talk_to_master(fetch=do_processing, recycle=recycle, unreserve=interrupted):
if do_processing:
if not self._slave.get_reserved():
self._idle_wait_until = time.time() + int(self._config["idle-sleep"])
if recycle:
self._recycle_wait_until = self._idle_wait_until + 3600
else:
processed = self._process()
if got_sighup and self._slave.get_reserved():
# keep this section at the front of the round-robin runnable queue
self._idle_wait_until = 0
self._recycle_wait_until = 0
else:
# put this section at the end of the round-robin runnable queue
self._idle_wait_until = time.time()
self._recycle_wait_until = time.time()
return processed
finally:
os.chdir(oldcwd)
return 0
def _talk_to_master(self, fetch=False, unreserve=False, recycle=False):
flush = self._count_submittable_logs() > 0
fetch = fetch and not self._slave.get_reserved()
if not flush and not fetch:
return True
try:
self._connect_to_master(recycle=recycle)
except KeyboardInterrupt:
raise
except MasterIsBusy:
logging.error("master is busy")
self._error_wait_until = time.time() + random.randrange(60, 180)
except MasterCantRecycle:
logging.error("master has nothing to recycle")
self._recycle_wait_until = max(time.time(), self._idle_wait_until) + 3600
except (MasterDidNotGreet, MasterIsCrazy, MasterCommunicationFailed, MasterNotOK):
logging.error("connection to master failed")
self._error_wait_until = time.time() + 900
self._slave.close()
else:
try:
for logdir in ["pass", "fail", "untestable"]:
for basename in os.listdir(logdir):
if basename.endswith(".log"):
fullname = os.path.join(logdir, basename)
self._slave.send_log(self._config.section, logdir, fullname)
os.remove(fullname)
if unreserve:
for logdir in ["new", "reserved"]:
for basename in os.listdir(logdir):
if basename.endswith(".log"):
fullname = os.path.join(logdir, basename)
self._slave.unreserve(fullname)
os.remove(fullname)
if fetch:
max_reserved = int(self._config["max-reserved"])
idle = self._slave.get_idle()
if idle > 0:
idle = min(idle, int(self._config["idle-sleep"]))
logging.info("idle (%d)" % idle)
if not recycle:
self._idle_wait_until = time.time() + idle
else:
self._recycle_wait_until = time.time() + idle
return 0
while len(self._slave.get_reserved()) < max_reserved and self._slave.reserve():
pass
self._slave.get_status(self._config.section)
except MasterNotOK:
logging.error("master did not respond with 'ok'")
self._error_wait_until = time.time() + 900
self._slave.close()
except (MasterIsCrazy, MasterCommunicationFailed):
logging.error("communication with master failed")
self._error_wait_until = time.time() + 900
self._slave.close()
else:
return True
return False
def _process(self):
global interrupted
self._slave.close()
packagenames = set([x[0] for x in self._slave.get_reserved()])
packages_files = {}
for distro in [self._config.get_distro()] + self._config.get_distros():
if distro not in packages_files:
try:
pf = piupartslib.packagesdb.PackagesFile()
pf.load_packages_urls(
self._distro_config.get_packages_urls(
distro,
self._config.get_area(),
self._config.get_arch()),
packagenames)
packages_files[distro] = pf
except IOError:
logging.error("failed to fetch packages file for %s" % distro)
self._error_wait_until = time.time() + 900
return 0
except KeyboardInterrupt:
interrupted = True
del packagenames
test_count = 0
self._check_tarball()
if not os.path.exists(self._get_tarball()):
self._error_wait_until = time.time() + 300
for package_name, version in self._slave.get_reserved():
self._throttle_if_overloaded()
if interrupted or got_sighup:
break
if not os.path.exists(self._get_tarball()):
logging.error("Missing chroot-tgz %s" % self._get_tarball())
break
test_count += 1
self._test_package(package_name, version, packages_files)
self._slave.forget_reserved(package_name, version)
self._talk_to_master(unreserve=interrupted)
return test_count
def _test_package(self, pname, pvers, packages_files):
global old_sigint_handler
old_sigint_handler = signal(SIGINT, sigint_handler)
logging.info("Testing package %s/%s %s" % (self._config.section, pname, pvers))
output_name = log_name(pname, pvers)
logging.debug("Opening log file %s" % output_name)
new_name = os.path.join("new", output_name)
output = file(new_name, "we")
output.write(time.strftime("Start: %Y-%m-%d %H:%M:%S %Z\n",
time.gmtime()))
distupgrade = len(self._config.get_distros()) > 1
command = self._config["piuparts-command"].split()
if self._config["piuparts-flags"]:
command.extend(self._config["piuparts-flags"].split())
if "http_proxy" in os.environ:
command.extend(["--proxy", os.environ["http_proxy"]])
if self._config["mirror"]:
mirror = self._config["mirror"]
if self._config["components"]:
mirror += " " + self._config["components"]
command.extend(["--mirror", mirror])
if self._config["tmpdir"]:
command.extend(["--tmpdir", self._config["tmpdir"]])
command.extend(["--arch", self._config.get_arch()])
command.extend(["-b", self._get_tarball()])
if not distupgrade:
command.extend(["-d", self._config.get_distro()])
command.append("--no-upgrade-test")
else:
for distro in self._config.get_distros():
command.extend(["-d", distro])
if self._config["keep-sources-list"] in ["yes", "true"]:
command.append("--keep-sources-list")
command.extend(["--apt", "%s=%s" % (pname, pvers)])
subdir = "fail"
ret = 0
if not distupgrade:
distro = self._config.get_distro()
if not pname in packages_files[distro]:
output.write("Package %s not found in %s\n" % (pname, distro))
ret = -10001
else:
package = packages_files[distro][pname]
if pvers != package["Version"]:
output.write("Package %s %s not found in %s, %s is available\n" % (pname, pvers, distro, package["Version"]))
ret = -10002
output.write("\n")
package.dump(output)
output.write("\n")
else:
distros = self._config.get_distros()
if distros:
# the package must exist somewhere
for distro in distros:
if pname in packages_files[distro]:
break
else:
output.write("Package %s not found in any distribution\n" % pname)
ret = -10003
# the package must have the correct version in the distupgrade target distro
distro = distros[-1]
if not pname in packages_files[distro]:
# the package may "disappear" in the distupgrade target distro
if pvers == "None":
pass
else:
output.write("Package %s not found in %s\n" % (pname, distro))
ret = -10004
else:
package = packages_files[distro][pname]
if pvers != package["Version"]:
output.write("Package %s %s not found in %s, %s is available\n" % (pname, pvers, distro, package["Version"]))
ret = -10005
for distro in distros:
output.write("\n[%s]\n" % distro)
if pname in packages_files[distro]:
packages_files[distro][pname].dump(output)
output.write("\n")
if ret == 0:
prev = "~"
for distro in distros:
if pname in packages_files[distro]:
v = packages_files[distro][pname]["Version"]
if not apt_pkg.version_compare(prev, v) <= 0:
output.write("Upgrade to %s requires downgrade: %s > %s\n" % (distro, prev, v))
ret = -10006
prev = v
else:
ret = -10010
if ret != 0:
subdir = "untestable"
if ret == 0:
output.write("Executing: %s\n" % " ".join(quote_spaces(command)))
ret, f = run_test_with_timeout(command, MAX_WAIT_TEST_RUN)
if not f or f[-1] != '\n':
f += '\n'
output.write(f)
lastline = f.split('\n')[-2]
if ret < 0:
output.write(" *** Process KILLED - exceed maximum run time ***\n")
elif not "piuparts run ends" in lastline:
ret += 1024
output.write(" *** PIUPARTS OUTPUT INCOMPLETE ***\n")
output.write("\n")
output.write("ret=%d\n" % ret)
output.write(time.strftime("End: %Y-%m-%d %H:%M:%S %Z\n",
time.gmtime()))
output.close()
if ret == 0:
subdir = "pass"
os.rename(new_name, os.path.join(subdir, output_name))
logging.debug("Done with %s: %s (%d)" % (output_name, subdir, ret))
signal(SIGINT, old_sigint_handler)
def log_name(package, version):
return "%s_%s.log" % (package, version)
def quote_spaces(vlist):
return ["'%s'" % x if ' ' in x else x for x in vlist]
def run_test_with_timeout(cmd, maxwait, kill_all=True):
def terminate_subprocess(p, kill_all):
pids = [p.pid]
if kill_all:
ps = subprocess.Popen(["ps", "--no-headers", "-o", "pid", "--ppid", "%d" % p.pid],
stdout=subprocess.PIPE)
stdout, stderr = ps.communicate()
pids.extend([int(pid) for pid in stdout.split()])
if p.poll() is None:
print 'Sending SIGINT...'
try:
os.killpg(os.getpgid(p.pid), SIGINT)
except OSError:
pass
# piuparts has 30 seconds to clean up after Ctrl-C
for i in range(60):
time.sleep(0.5)
if p.poll() is not None:
break
if p.poll() is None:
print 'Sending SIGTERM...'
p.terminate()
# piuparts has 5 seconds to clean up after SIGTERM
for i in range(10):
time.sleep(0.5)
if p.poll() is not None:
break
if p.poll() is None:
print 'Sending SIGKILL...'
p.kill()
for pid in pids:
if pid > 0:
try:
os.kill(pid, SIGKILL)
print "Killed %d" % pid
except OSError:
pass
logging.debug("Executing: %s" % " ".join(quote_spaces(cmd)))
stdout = ""
p = subprocess.Popen(cmd, preexec_fn=os.setpgrp,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
if maxwait > 0:
signal(SIGALRM, alarm_handler)
alarm(maxwait)
try:
stdout, stderr = p.communicate()
alarm(0)
except Alarm:
terminate_subprocess(p, kill_all)
return -1, stdout
except KeyboardInterrupt:
print '\nSlave interrupted by the user, cleaning up...'
try:
terminate_subprocess(p, kill_all)
except KeyboardInterrupt:
print '\nTerminating piuparts was interrupted... manual cleanup still neccessary.'
raise
raise
ret = p.returncode
if ret in [124, 137]:
# process was terminated by the timeout command
ret = -ret
return ret, stdout
def create_chroot(config, tarball, distro):
command = config["piuparts-command"].split()
if config["piuparts-flags"]:
command.extend(config["piuparts-flags"].split())
if "http_proxy" in os.environ:
command.extend(["--proxy", os.environ["http_proxy"]])
if config["mirror"]:
mirror = config["mirror"]
if config["components"]:
mirror += " " + config["components"]
command.extend(["--mirror", mirror])
if config["tmpdir"]:
command.extend(["--tmpdir", config["tmpdir"]])
command.extend(["--arch", config.get_arch()])
command.extend(["-d", distro])
command.extend(["-s", tarball + ".new"])
command.extend(["--apt", "dpkg"])
output_name = tarball + ".log"
with open(output_name, "we") as output:
try:
fcntl.flock(output, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError:
logging.info("Creation of tarball %s already in progress." % tarball)
else:
logging.info("Creating new tarball %s" % tarball)
output.write(time.strftime("Start: %Y-%m-%d %H:%M:%S %Z\n\n",
time.gmtime()))
output.write("Executing: " + " ".join(quote_spaces(command)) + "\n\n")
logging.debug("Executing: " + " ".join(quote_spaces(command)))
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout:
output.write(line)
logging.debug(">> " + line.rstrip())
p.wait()
output.write(time.strftime("\nEnd: %Y-%m-%d %H:%M:%S %Z\n",
time.gmtime()))
if os.path.exists(tarball + ".new"):
os.rename(tarball + ".new", tarball)
else:
logging.error("Tarball creation failed, see %s" % output_name)
def create_file(filename, contents):
f = file(filename, "w")
f.write(contents)
f.close()
def main():
setup_logging(logging.INFO, None)
signal(SIGHUP, sighup_handler)
# For supporting multiple architectures and suites, we take command-line
# argument(s) referring to section(s) in the configuration file.
# If no argument is given, the "sections" entry from the "global" section
# is used.
section_names = []
global_config = Config(section="global")
global_config.read(CONFIG_FILE)
if global_config["proxy"]:
os.environ["http_proxy"] = global_config["proxy"]
if len(sys.argv) > 1:
section_names = sys.argv[1:]
else:
section_names = global_config["sections"].split()
section_names += global_config["basetgz-sections"].split()
persistent_connection = Slave()
sections = []
for section_name in section_names:
try:
sections.append(Section(section_name, persistent_connection))
except MissingSection:
# ignore unknown sections
pass
if not sections:
logging.error("no sections found")
return
while True:
global got_sighup
test_count = 0
for section in sorted(sections, key=lambda section: (section.precedence(), section.sleep_until())):
test_count += section.run(do_processing=(test_count == 0))
if test_count == 0 and got_sighup:
# clear SIGHUP state after flushing all sections
got_sighup = False
continue
if test_count == 0:
# try to recycle old logs
# round robin recycling of all sections is ensured by the recycle_wait_until timestamps
idle_until = min([section.sleep_until() for section in sections])
for section in sorted(sections, key=lambda section: section.sleep_until(recycle=True)):
test_count += section.run(recycle=True)
if test_count > 0 and idle_until < time.time():
break
if interrupted:
raise KeyboardInterrupt
if test_count == 0 and not got_sighup:
now = time.time()
sleep_until = min([now + int(global_config["idle-sleep"])] + [section.sleep_until() for section in sections])
if (sleep_until > now):
to_sleep = max(60, sleep_until - now)
persistent_connection.close()
logging.info("Nothing to do, sleeping for %d seconds." % to_sleep)
time.sleep(to_sleep)
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print ''
print 'Slave interrupted by the user, exiting...'
sys.exit(1)
# vi:set et ts=4 sw=4 :
piuparts-0.64ubuntu1/TODO 0000664 0000000 0000000 00000015466 12517712417 012241 0 ustar Things to do for piuparts
=========================
Please also check the BTS, especially the bugs with a severity higher than
wishlist!
for 0.6x:
- README_server.txt: rewrite style a bit more. its super easy to setup now!
- ==== piuparts.debian.org specific configuration
^^^^^^^ scripts should be the headline, not piu.d.o
- move more bits from README_pejacevic.txt to README_server.txt
- split out README_protocol and README_piuparts.conf? -> in piuparts.conf manpage maybe?
- support multiple architectures: #762308
- piuparts-report should have a list of available arch and list packages
only available on untested archs in a new state
"(depends-)not-available-on-tested-archs"
- master should (per default) only schedule packages which are not available
on the master arch to slaves of different archs ->
"schedule-evenly-to-slaves = no"
- once that works, update README_pejacevic: search for "soon shall go into operation..." :)
- piuparts-master: keep track of to whom a reservation was given
- more stats and graphs:
- new section stats page:
- packages processed per day and section, master writes submissions.txt
since 0.45 for all sections.
- generate simple diagrams: number of source + binary packages in all
single distros: lenny, squeeze, wheezy, jessie, sid.
- graph about piuparts stati for all sections combined? (possible ignore
successful)
- master should create the master and backup directories, if they dont exit. If master does that remove that sentence from README_server.txt again. same with slave and tmp.
- piuparts.conf.pejacevic: maybe use mirror via nfs (faster)
- also test packages from security.d.o
=> is jessie-pu sufficient? this should quickly include these packages
- maybe compress all logfiles
- look for a solution to use the global debian mirror for debian-backports,
too, to avoid hardcoding a specific mirror in distros.conf
- if it weren't for 'slave-bin/slave_cleanup', the slave would only need
rights to run "sudo piuparts" but nothing else. If we can clean this up,
the sudoers.d should recommend sudo (lsof|kill|umount) for admins.
- if there were real schroot support, piuparts could be used without sudo.
(#708663)
- use network namespaces to disable network during the tests:
- < weasel> says: unshare --uts --ipc --net -- sh -c 'ip addr add 127.0.0.1/8 dev lo && ip link set dev lo up && stuff'
and points to https://anonscm.debian.org/gitweb/?p=mirror/dsa-puppet.git;a=blob;f=modules/porterbox/files/dd-schroot-cmd#l104
- problem might be access to the mirror, either (bind mounted) nfs access will still work in the chroots or do as its done on the porterboxes:
apt-get install -d , unshare apt-get install foo
- add a sample config with all possible keys set to some useful value
(like /usr/share/doc/apt/examples/configure-index.gz)
- generate piuparts.1.txt automatically from piuparts.py - see this blog post
for a nice howto:
http://andialbrecht.wordpress.com/2009/03/17/creating-a-man-page-with-distutils-and-optparse/
- though this seems pretty complicated... maybe rather grep for
parser.add_option and help= in piuparts.py ?!
- requires merging all the additional infomation in piuparts.1.txt into
piuarts.py
- parsing piuparts --help output may be easier than parsing piuparts.py
- elso: examples are duplicated in piuparts.1.txt and README.txt
- check the logfiles (especially pass/) for
- "Exception in thread"
- java stacktraces
- "Can't locate .* in @INC"
- we should probably have an install test with --enable-recommends and
without --warn-on-others to avoid adding artificial barriers where package
subsets are configured
(wheezy2jessie-rcmd is *not* the solution for this)
- record file ownership by user/group name, not id
new dynamic system users added to the base system may have a lower id in the
reference system than after actually testing some packages
e.g. group of /usr/lib/dbus-1.0/dbus-daemon-launch-helper (wheezy2jessie-pu)
- there was some issue (not) terminating a test run by the slave with ^C^C,
forgot the details
- report actually ignored files/patterns ROT13 encoded to be able to spot and
reschedule such tests
- p-r: in the section summary page, report the piuparts flags being used
- p-s: report age of the basetgz being used
for 0.7x and later:
- install from git/Makefile: remove the need for /etc/piuparts
- accept a PIUPARTS_CONF environment variable everywhere to point to a different
piuparts.conf
- write reportbug-like wrapper for mass bug filing (start simple, make it more
sophisticated later).
- rework known_problems:
- use a number prefix for sorting
- add title information
- piuparts-report: "discover" the available known_problems, dont hardcode the
list
- drop _issue/_error duplication, have flags inside to indicate thether to
generate _issues.tpl (pass/) and/or _error.tpl (fail/ bugged/ affected/)
- rework known problems to a python-friendlier format
- the templates used by update-reports.py and detect_well_known_errors should
be taken from /etc/piuparts/templates/ and not be included in the python source
- a redirect of http://piuparts.d.o/foo to http://p.d.o/source/f/foo.html would
be nice
for 0.8x and later:
- find_default_debian_mirrors:
- check whether find_default_debian_mirrors produces something useful if
sources.list does not exist (and sources.list.d/*.list is there instead)
- maybe just copy sources.list(.d/*) instead?
- make it possible to call aptitude (or similar) instead of apt-get and allow to
override the commandline arguments.
- mount perhaps others (usbfs, sysfs, etc.) in the chroot
might be a good idea because some packages might need this.
- rewrite piuparts-analyze to run over all sections and cache BTS responses
- "decorate" (strike-through) bug links generated by piuparts-analyze to
indicate resolved state (take package version into account!)
- report:
- write stats about the reasons for failures, as its done with shell scripts
now (piuparts-analyze.py is an existing "fragment".)
- RSS feeds of logs
- do more fancy R graphs, eg. also per state
- link (and target) to piuparts.d.o configuration is static to pejacevic. should
refer to the actual hosts configuration if running somewhere else
- not sure if it's a sensible thing to to, but provide a way to turn off
debugging output for piuparts.py - see
http://docs.python.org/library/logging.html
- commandline-switches for all programms
- move shell cronjobs functionality into master, slave & report
- automated testing of piuparts using an archive of known broken packages:
- create archive of broken packages to provide test cases for piuparts testing.
- create emacspeak-broken-dpkg-preconfigure package for broken repo. (then later
put more broken packages in there and use that for testing piuparts)
piuparts-0.64ubuntu1/conf/ 0000775 0000000 0000000 00000000000 12536542721 012462 5 ustar piuparts-0.64ubuntu1/conf/piuparts.conf.sample 0000664 0000000 0000000 00000002152 12536542721 016460 0 ustar #
# This is the configuration file for piuparts running in master-slave mode.
# Usually it's placed in /etc/piuparts/piuparts.conf
#
# You MUST make sure that master-host, master-user, master-directory, and
# mirror are set correctly.
#
[global]
sections = sid
mirror = http://httpredir.debian.org/debian
master-host = localhost
master-user = piupartsm
piuparts-command = sudo piuparts --scriptsdir /etc/piuparts/scripts
master-directory = /var/lib/piuparts/master
slave-directory = /var/lib/piuparts/slave
basetgz-directory = /var/cache/piuparts/basetgz
output-directory = /var/lib/piuparts/htdocs
tmpdir = /var/cache/piuparts/tmp
doc-root = /piuparts/
idle-sleep = 300
max-tgz-age = 604800
max-reserved = 50
expire-old-days = 120
reschedule-old-days = 90
reschedule-old-count = 150
expire-fail-days = 45
reschedule-fail-days = 30
reschedule-fail-count = 25
[sid]
precedence = 1
description = "Debian sid / main"
piuparts-flags = --no-symlinks
distro = sid
# area = main
# arch = amd64
upgrade-test-distros =
debug = no
## another example:
## [s-p-u-i386]
## distro = stable-proposed-updates
## # area = main
## arch = i386
piuparts-0.64ubuntu1/conf/piuparts-master.conf 0000664 0000000 0000000 00000000371 12536542721 016472 0 ustar Alias /piuparts /var/lib/piuparts/htdocs
Require all granted
Options indexes
IndexOptions FancyIndexing NameWidth=*
AddType text/plain .log
AddDefaultCharset utf-8
# vim:set syn=apache:
piuparts-0.64ubuntu1/conf/crontab-master.in 0000664 0000000 0000000 00000001767 12517712417 015746 0 ustar # m h dom mon dow (0|7=sun,1=mon) command
#
# cleanup $HTDOCS/daily.lock
#
@reboot @sharedir@/piuparts/master/master_cleanup
#
# generate reports twice a day
# (dinstall runs 1|7|13|19:52, so this is long after mirror pushes...)
#
0 0,6,12,18 * * * @sharedir@/piuparts/master/generate_daily_report
#
# reschedule old logs twice a day
#
00 3,15 * * * @sharedir@/piuparts/master/reschedule_oldest_logs
#
# monitor for problems once a day
# - these may result in packages being retested
# - if that's not the case, run them from within generate_daily_report
#
30 3-21/6 * * * @sharedir@/piuparts/master/detect_network_issues
45 3-21/6 * * * @sharedir@/piuparts/master/detect_piuparts_issues
0 22 * * * @sharedir@/piuparts/master/detect_archive_issues
30 22 * * * @sharedir@/piuparts/master/report_untestable_packages
0 23 * * * @sharedir@/piuparts/master/report_stale_reserved_packages
#
# misc
#
0 2 * * * @sharedir@/piuparts/master/prepare_backup
55 23 * * * @sharedir@/piuparts/master/gather_bts_stats
piuparts-0.64ubuntu1/conf/distros.conf 0000664 0000000 0000000 00000006715 12517712417 015031 0 ustar #
# Omitted fields will be set to defaults and completely "missing"
# [distribution] entries will automatically be generated as follows:
#
# []
# uri =
# distribution =
# components =
# depends =
# candidates =
# target-release =
#
# These are the standard fields for sources.list entries:
# uri, distribution, components
#
# A non-empty "target-release" will add a -t argument to apt-get:
# apt-get -t ...
#
# The "depends" entry can be used to refer to the "parent distribution"
# (e.g. stable) of a "partial distribution" (e.g. stable-backports).
# These are resolved recursively and will be made available in the
# sources.list file.
#
# The "candidates" entry can be used to build a (virtually) merged
# Packages file from one or more partial distribution (and maybe a full
# parent distribution). This is used for selecting (package,version)
# tuples to be tested. No recursive lookup.
[etch]
uri = http://archive.debian.org/debian
[lenny]
uri = http://archive.debian.org/debian
[squeeze/updates]
uri = http://security.debian.org
depends = squeeze
[squeeze-updates]
depends = squeeze
[squeeze-proposed-updates]
depends = squeeze
[squeeze-proposed]
uri = None
depends = squeeze squeeze/updates squeeze-updates squeeze-proposed-updates
candidates = squeeze squeeze/updates squeeze-proposed-updates
[squeeze-backports]
uri = http://ftp.de.debian.org/debian-backports
depends = squeeze squeeze/updates
target-release = squeeze-backports
[squeeze-backports-sloppy]
uri = http://ftp.de.debian.org/debian-backports
depends = squeeze squeeze-backports
target-release = squeeze-backports-sloppy
[squeeze-lts]
depends = squeeze squeeze/updates
target-release = squeeze-lts
[wheezy/updates]
uri = http://security.debian.org
depends = wheezy
[wheezy-updates]
depends = wheezy
[wheezy-proposed-updates]
depends = wheezy
[wheezy-proposed]
uri = None
depends = wheezy wheezy/updates wheezy-updates wheezy-proposed-updates
candidates = wheezy wheezy/updates wheezy-proposed-updates
[wheezy-backports]
depends = wheezy wheezy/updates
target-release = wheezy-backports
[wheezy-backports-sloppy]
depends = wheezy wheezy-backports
target-release = wheezy-backports-sloppy
[jessie/updates]
uri = http://security.debian.org
depends = jessie
[jessie-updates]
depends = jessie
[jessie-proposed-updates]
depends = jessie
[jessie-proposed]
uri = None
depends = jessie jessie/updates jessie-updates jessie-proposed-updates
candidates = jessie jessie/updates jessie-proposed-updates
[jessie-backports]
depends = jessie jessie/updates
target-release = jessie-backports
[stretch/updates]
uri = http://security.debian.org
depends = stretch
[stretch-updates]
depends = stretch
[stretch-proposed-updates]
depends = stretch
[stretch-proposed]
uri = None
depends = stretch stretch/updates stretch-updates stretch-proposed-updates
candidates = stretch stretch/updates stretch-proposed-updates
[stretch-backports]
depends = stretch stretch/updates
target-release = stretch-backports
# alias
[stable]
distribution = jessie
# alias
[testing]
distribution = stretch
[experimental]
depends = sid
target-release = experimental
# It's also possible to have "virtual" entries by setting uri to
# the string "None". This allows e.g. to combine several partial
# distributions. Such virtual distros can be used for standalone
# piuparts runs, but not in master-slave setup.
[squeeze-current]
uri = None
depends = squeeze/updates squeeze-updates
piuparts-0.64ubuntu1/conf/piuparts-slave.sudoers 0000664 0000000 0000000 00000000517 12452567511 017053 0 ustar #
# copy this file to /etc/sudoers.d/piuparts-slave
#
# The piuparts slave needs to handle chroots.
piupartss ALL = NOPASSWD: /usr/sbin/piuparts *, \
/bin/umount /srv/piuparts.debian.org/tmp/tmp*, \
/usr/bin/test -f /srv/piuparts.debian.org/tmp/tmp*, \
/usr/bin/rm -rf --one-file-system /srv/piuparts.debian.org/tmp/tmp*
piuparts-0.64ubuntu1/conf/crontab-slave.in 0000664 0000000 0000000 00000001220 12517712417 015545 0 ustar # m h dom mon dow (0|7=sun,1=mon) command
#
# start slave_run automatically after reboots
#
@reboot @sharedir@/piuparts/slave/slave_cleanup ; @sharedir@/piuparts/slave/slave_run
42 * * * * @sharedir@/piuparts/slave/slave_cleanup ; ! @sharedir@/piuparts/slave/slave_run >/dev/null 2>&1 || echo "piuparts-slave started by cron"
#
# monitor slave session every hour
#
16 * * * * @sharedir@/piuparts/slave/detect_slave_problems
#
# monitor for problems every six hours
#
23 */6 * * * @sharedir@/piuparts/slave/detect_leftover_processes
#
# monitor for cruft in the temporary directory once a day
#
00 0 * * * @sharedir@/piuparts/slave/detect_tmp_cruft
piuparts-0.64ubuntu1/known_problems/ 0000775 0000000 0000000 00000000000 12536542721 014574 5 ustar piuparts-0.64ubuntu1/known_problems/piuparts-depends-dummy_issue.conf 0000664 0000000 0000000 00000000460 12452567512 023275 0 ustar #
# detect problems where piuparts-depends-dummy.deb was not installed
#
PATTERN='ERROR: Installation of piuparts-depends-dummy FAILED'
WHERE='pass'
ISSUE=1
HEADER='Problems installing piuparts-depends-dummy.deb'
HELPTEXT='
apt chose to remove piuparts-depends-dummy.deb instead of fixing it.
'
piuparts-0.64ubuntu1/known_problems/ldd_inadequate_issue.conf 0000664 0000000 0000000 00000000570 12452567512 021622 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* ldd'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'ldd' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'ldd' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/broken_binfmt_detector_inadequate_issue.conf 0000664 0000000 0000000 00000000760 12452567512 025570 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* broken-binfmt-detector'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'broken-binfmt-detector' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'broken-binfmt-detector' which indicates a bug: The detector registered with update-binfmts(8) does not exist.
"
././@LongLink 0000644 0000000 0000000 00000000146 00000000000 011604 L ustar root root piuparts-0.64ubuntu1/known_problems/bin_or_sbin_binary_requires_usr_lib_library_inadequate_issue.conf piuparts-0.64ubuntu1/known_problems/bin_or_sbin_binary_requires_usr_lib_library_inadequate_issue.con0000664 0000000 0000000 00000000760 12452567512 031723 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* bin-or-sbin-binary-requires-usr-lib-library'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'bin-or-sbin-binary-requires-usr-lib-library' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'bin-or-sbin-binary-requires-usr-lib-library' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/owned_files_after_purge_error.conf 0000664 0000000 0000000 00000001144 12452567512 023537 0 ustar #
# detect packages with owned files after purge (policy 6.8)
#
PATTERN='owned by:'
EXCLUDE_PATTERN=',|usr/local/'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with owned files after purge'
HELPTEXT='
WARNING: this list might contain false positives.
#316521: dpkg: incomplete cleanup of empty directories
Packages need to remove owned files after purge, see
https://www.debian.org/doc/debian-policy/ch-files.html#s10.7.3
'
piuparts-0.64ubuntu1/known_problems/maintainer_script_issue.conf 0000664 0000000 0000000 00000000547 12452567512 022376 0 ustar #
# detect packages in successfully-tested state that had maintainer script failures
#
PATTERN='subprocess .*(pre|post)-(installation|removal) script returned error'
WHERE='pass'
ISSUE=0
HEADER='Packages in state successfully-tested but logfile contains a maintainer script failure'
HELPTEXT='
This is a somewhat unclassified issue at the moment.
'
piuparts-0.64ubuntu1/known_problems/conffile_prompt_error.conf 0000664 0000000 0000000 00000002321 12452567512 022042 0 ustar #
# detect packages with failed because they prompt due to a modified conffile
#
PATTERN='EOF on stdin at conffile prompt'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs with the string "EOF on stdin at conffile prompt"'
HELPTEXT='
The piuparts upgrade test failed because dpkg detected a conffile as being modified and then prompted the user for an action. As there is no user input, this fails. But this is not the real problem, the real problem is that this prompt shows up in the first place, as there was nobody modifying this conffile at all, the package has just been installed and upgraded...
This is explained in detail in policy 10.7.3 at https://www.debian.org/doc/debian-policy/ch-files.html#s10.7.3 which says "[These scripts handling conffiles] must not ask unnecessary questions (particularly during upgrades), and must otherwise be good citizens."
According to the thread started at 200908191215.05079.holger@layer-acht.org these bugs are to be filed with severity serious.
'
piuparts-0.64ubuntu1/known_problems/processes_running_error.conf 0000664 0000000 0000000 00000002054 12452567512 022425 0 ustar #
# detect packages which failed because of processes are running inside chroot
#
PATTERN='ERROR: FAIL: Processes are running inside chroot'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because of processes left behind'
HELPTEXT='
There were processes running inside the chroot at the end of the piuparts run.
This is probably due to directly calling /etc/rc.d/ scripts in packages maintainer scripts, which is a violation of policy 9.3.3.2 and must be replaced by using invoke-rc.d (which will respect an optionally existing policy-rc.d) - see
https://www.debian.org/doc/debian-policy/ch-opersys.html#s9.3.3, /usr/share/doc/sysv-rc/README.invoke-rc.d.gz and /usr/share/doc/sysv-rc/README.policy-rc.d.gz.
According to the thread started at 200908061127.35727.holger@layer-acht.org these bugs are to be filed with severity serious.
'
piuparts-0.64ubuntu1/known_problems/unknown_inadequate_issue.conf 0000664 0000000 0000000 00000001177 12452567512 022562 0 ustar #
# detect packages which have the string "Found unknown tags running adequate" in their logs
#
PATTERN='(FAIL|WARN): Found unknown tags running adequate'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER='Packages which have logs with the string "Found unknown tags running adequate"'
HELPTEXT='
Sometimes new types of problems are detected by adequate, which classifies them using tags. When this happens these new tags need to be made known to piuparts. Please notify piuparts-devel@lists.alioth.debian.org.
'
piuparts-0.64ubuntu1/known_problems/missing-symbol-version-information_inadequate_issue.conf 0000664 0000000 0000000 00000000725 12452567512 030043 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* missing-symbol-version-information'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'missing-symbol-version-information' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'missing-symbol-version-information' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/alternatives_after_purge_issue.conf 0000664 0000000 0000000 00000001234 12452567512 023741 0 ustar #
# detect packages with unowned files in /etc/alternatives after purge (policy 6.8)
#
PATTERN='/etc/alternatives/.*not owned'
WHERE='pass'
ISSUE=1
HEADER='Packages with leftover alternatives after purge'
HELPTEXT='
Packages with unowned files in /etc/alternatives after purge (violating policy 6.8) see
https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-removedetails
Alternatives are usually registered with update-alternatives in postinst configure and need to be unregistered again in prerm remove.
'
piuparts-0.64ubuntu1/known_problems/problems_and_no_force_error.conf 0000664 0000000 0000000 00000001232 12452567512 023173 0 ustar #
# detect packages with problems because of not enough force
#
PATTERN='E: There are problems and -y was used without --force-yes'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because of not enough force'
HELPTEXT='
The piuparts logfile for these packages contains the string
E: There are problems and -y was used without --force-yes
, which is usually an indication, that an essential package needs to be removed to install this package. As piuparts does not use that much force, the piuparts test fails.
This is usually not an error in the package and it needs to be seen how piuparts should deal with it.
'
piuparts-0.64ubuntu1/known_problems/pre_installation_script_error.conf 0000664 0000000 0000000 00000000533 12452567512 023612 0 ustar #
# detect packages which failed because pre-installation maintainer script failed
#
PATTERN='subprocess .*pre-installation script returned error'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because pre-installation maintainer script failed'
HELPTEXT='
This is a somewhat unclassified failure at the moment.
'
piuparts-0.64ubuntu1/known_problems/broken_symlinks_error.conf 0000664 0000000 0000000 00000001036 12452567512 022067 0 ustar #
# detect packages which have the string "Broken symlinks" in their logs
#
PATTERN='(WARN|FAIL): Broken symlink'
WHERE='fail bugged affected'
ISSUE=1
HEADER='Packages which have logs with the string "Broken symlinks"'
HELPTEXT='
This is clearly an error, but as there are too many of this kind, piuparts can be configured to not fail if it detects broken symlinks. Another option is not to test for broken symlinks. See the piuparts manpage for details.
'
piuparts-0.64ubuntu1/known_problems/immediate_configuration_error.conf 0000664 0000000 0000000 00000000557 12452567512 023552 0 ustar #
# detect packages which failed because apt could not perform immediate configuration
#
PATTERN='E: Could not perform immediate configuration on'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because apt could not perform immediate configuration'
HELPTEXT='
This is a bug in apt, but it has to be worked around in some packages.
'
piuparts-0.64ubuntu1/known_problems/incompatible_licenses_inadequate_issue.conf 0000664 0000000 0000000 00000000656 12452567512 025417 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* incompatible-licenses'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'incompatible-licenses' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'incompatible-licenses' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/broken_binfmt_interpreter_inadequate_issue.conf 0000664 0000000 0000000 00000000774 12452567512 026327 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* broken-binfmt-interpreter'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'broken-binfmt-interpreter' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'broken-binfmt-interpreter' which indicates a bug: The interpreter registered with update-binfmts(8) does not exist.
"
piuparts-0.64ubuntu1/known_problems/used_exception_issue.conf 0000664 0000000 0000000 00000000406 12452567512 021673 0 ustar #
# report packages that used a piuparts exception to pass a test
#
PATTERN='piuparts exception for package'
WHERE='pass'
ISSUE=1
HEADER='Packages that used a piuparts exception'
HELPTEXT='
These packages needed a piuparts exception to pass the test.
'
piuparts-0.64ubuntu1/known_problems/command_not_found_issue.conf 0000664 0000000 0000000 00000001453 12452567512 022351 0 ustar #
# detect packages which passed the piuparts test but have the string "command not found" in their logs
#
PATTERN='command not found|: not found'
WHERE='pass'
ISSUE=1
HEADER='Packages which passed the piuparts test but have logs with the string "command not found"'
HELPTEXT='
From the third paragraph about the meaning of the depends field in
https://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps:
The Depends field should also be used if the postinst, prerm or postrm scripts
require the package to be present in order to run. __Note, however, that the
postrm cannot rely on any non-essential packages to be present during the
purge phase__.
'
piuparts-0.64ubuntu1/known_problems/unowned_files_after_purge_issue.conf 0000664 0000000 0000000 00000001440 12452567512 024100 0 ustar #
# detect packages with unowned files after purge (policy 6.8)
#
PATTERN='not owned'
EXCLUDE_PATTERN="/usr/share/mime/|usr/local/"
WHERE='pass'
ISSUE=1
HEADER='Packages with unowned files after purge'
HELPTEXT='
WARNING: this list might contain false positives.
One group of them are packages with files in /usr/share/mime
- those are bugs from shared-mime-info (#527063) and have been ignored for this list.
There are probably others like this as well.
Packages with unowned files after purge (violating policy 6.8) see
https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-removedetails
'
piuparts-0.64ubuntu1/known_problems/dependency_error.conf 0000664 0000000 0000000 00000001035 12452567512 020773 0 ustar #
# detect packages with unsatisfied dependencies
#
PATTERN='E: Broken packages|E: Unable to correct problems, you have held broken packages.|E: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because of unsatisfied dependencies'
HELPTEXT='
Usually this is caused by some unsatisfied (versioned) Depends/Conflicts/Replaces.
These packages will be automatically rescheduled for testing seven days after they failed.
'
piuparts-0.64ubuntu1/known_problems/installs_over_symlink_error.conf 0000664 0000000 0000000 00000001152 12452567512 023307 0 ustar #
# detect packages which have the string "dirname part contains a symlink" in their logs
#
PATTERN='silently overwrites files via directory symlinks|dirname part contains a symlink'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages that install something over existing symlinks'
HELPTEXT='
Installing anything over a symlink opens a can of worms -
this causes problems on upgrades while switching between directory and symlink
or if the symlink is ever changed.
Piuparts looks at all $pathname known to dpkg and checks for
$(dirname $pathname) != $(readlink $(dirname $pathname))
'
piuparts-0.64ubuntu1/known_problems/initdscript_lsb_header_issue.conf 0000664 0000000 0000000 00000002615 12517712417 023363 0 ustar #
# detect packages with an update-rc.d warning
#
PATTERN='update-rc.d: warning.*do not match LSB|service.*already provided'
WHERE='fail bugged affected pass'
ISSUE=1
HEADER='Packages with logs with the string "update-rc.d: warning.*do not match LSB"'
HELPTEXT='
Some packages have inconsistency between the init.d script headers
used with dependency based boot sequencing and the runlevels specified
on the update-rc.d command line and used by the legacy boot ordering.
Such inconsistency is most likely a bug in the package, as the two
ways of ordering init.d scripts should enable and disable the scripts
in the same runlevels while Debian migrate to dependency based boot
sequencing.
Such inconsinstency is reported like this when a postinst script call
update-rc.d
update-rc.d: warning: initdscript start runlevel arguments (2 3 4 5) do not match LSB Default-Start values (S)
update-rc.d: warning: initdscript stop runlevel arguments (0 1 6) do not match LSB Default-Stop values (none)
Such reports are most likely bugs in the package calling update-rc.d,
and should be reported and fixed in the individual packages.
See the paragraph "How to solve migration problems" at https://wiki.debian.org/LSBInitScripts/DependencyBasedBoot for information how to fix these issues.
'
piuparts-0.64ubuntu1/known_problems/packages_have_been_kept_back_error.conf 0000664 0000000 0000000 00000000515 12452567512 024434 0 ustar #
# detect possible dependency issues
#
PATTERN='packages have been kept back'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with logs with the string "packages have been kept back"'
HELPTEXT='
"packages have been kept back" usually indicates some dependency issue
that caused apt to not fully upgrade the system.
'
piuparts-0.64ubuntu1/known_problems/files_in_usr_local_error.conf 0000664 0000000 0000000 00000000666 12452567512 022521 0 ustar #
# detect packages which leave stuff in /usr/local (see policy 9.1.2)
#
PATTERN='usr/local.+not owned'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with files and/or directories in /usr/local/ after purge'
HELPTEXT='
This is a violation of policy 9.1.2: see
https://www.debian.org/doc/debian-policy/ch-opersys.html#s9.1.2.
'
piuparts-0.64ubuntu1/known_problems/owned_files_after_purge_issue.conf 0000664 0000000 0000000 00000001065 12452567512 023540 0 ustar #
# detect packages with owned files after purge (policy 6.8)
#
PATTERN='owned by:'
WHERE='pass'
ISSUE=1
HEADER='Packages with owned files after purge'
HELPTEXT='
WARNING: this list might contain false positives.
#316521: dpkg: incomplete cleanup of empty directories
Packages need to remove owned files after purge, see
https://www.debian.org/doc/debian-policy/ch-files.html#s10.7.3
'
piuparts-0.64ubuntu1/known_problems/db_setup_error.conf 0000664 0000000 0000000 00000001445 12452567512 020467 0 ustar #
# detect packages with failed to install due to problems configuring the db - see #595652
#
PATTERN='(warning: database package not installed|dbconfig-common: .* configure: (aborted|noninteractive fail).|updating database schema for .*...command failed with code 0|psql: could not connect to server: No such file or directory|DBI connect.* failed: could not connect to server|pg_pconnect\(\): Unable to connect to PostgreSQL server|Unable to connect to MySQL server|unable to connect to mysql server)'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because installation failed because no database could be connected.'
HELPTEXT='
Just how buggy these packages really are is discussed in #595652 at the moment.
'
piuparts-0.64ubuntu1/known_problems/unclassified_failures.conf 0000664 0000000 0000000 00000000471 12452567512 022012 0 ustar #
# report for failures that didn't match any known problem
#
PATTERN='QQQQQ_d195eab29de40b96b44ee8646c0d10d97171d454_dummy_pattern_QQQQQ'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with unclassified failures detected'
HELPTEXT='
Please investigate and improve detection of known error types!
'
piuparts-0.64ubuntu1/known_problems/symbol-size-mismatch_inadequate_issue.conf 0000664 0000000 0000000 00000000653 12452567512 025141 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* symbol-size-mismatch'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'symbol-size-mismatch' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'symbol-size-mismatch' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/obsolete_conffiles_issue.conf 0000664 0000000 0000000 00000000767 12452567512 022533 0 ustar #
# detect packages that leave obsolete conffiles after upgrades
#
PATTERN='OBSOLETE CONFFILE'
WHERE='pass'
ISSUE=1
HEADER='Packages leaving obsolete conffiles after upgrade'
HELPTEXT='
Packages that leave obsolete conffiles after upgrade.
Using
dpkg-maintscript-helper rm_conffile
via dh_installdeb package.maintscript files is the recommended way to clean them up.
There may be false positives, e.g. if a conffile was converted to a maintainer script managed configuration file.
'
piuparts-0.64ubuntu1/known_problems/db_setup_issue.conf 0000664 0000000 0000000 00000001425 12452567512 020464 0 ustar #
# detect packages with failed to install due to problems configuring the db - see #595652
#
PATTERN='(warning: database package not installed|dbconfig-common: .* configure: (aborted|noninteractive fail).|updating database schema for .*...command failed with code 0|psql: could not connect to server: No such file or directory|DBI connect.* failed: could not connect to server|pg_pconnect\(\): Unable to connect to PostgreSQL server|Unable to connect to MySQL server|unable to connect to mysql server)'
WHERE='pass'
ISSUE=1
HEADER='Packages with failed logs because installation failed because no database could be connected.'
HELPTEXT='
Just how buggy these packages really are is discussed in #595652 at the moment.
'
piuparts-0.64ubuntu1/known_problems/undefined_symbol_inadequate_issue.conf 0000664 0000000 0000000 00000000637 12452567512 024411 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* undefined-symbol'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'undefined-symbol' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'undefined-symbol' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/cron_error_after_removal_error.conf 0000664 0000000 0000000 00000001461 12452567512 023740 0 ustar #
# detect packages with cron errors after the package has been removed
#
PATTERN='(FAIL: Cron file .* has output with package removed|ERROR: Command failed.*./etc/cron\..*/.*.])'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because a cron file has output and/or exits with error after the package has been removed'
HELPTEXT='
From https://www.debian.org/doc/debian-policy/ch-opersys.html#s9.5
The scripts or crontab entries in these directories should check if all
necessary programs are installed before they try to execute them. Otherwise,
problems will arise when a package was removed but not purged since
configuration files are kept on the system in this situation.
'
piuparts-0.64ubuntu1/known_problems/unowned_lib_symlink_issue.conf 0000664 0000000 0000000 00000000327 12452567512 022732 0 ustar #
# detect unowned symlinks in library directories
#
PATTERN='UNOWNED SYMLINK'
WHERE='pass'
ISSUE=1
HEADER='Unowned symlinks is library directories'
HELPTEXT='
These should rather be shipped in packages.
'
piuparts-0.64ubuntu1/known_problems/packages_have_been_kept_back_issue.conf 0000664 0000000 0000000 00000000475 12452567512 024440 0 ustar #
# detect possible dependency issues
#
PATTERN='packages have been kept back'
WHERE='pass'
ISSUE=1
HEADER='Packages with logs with the string "packages have been kept back"'
HELPTEXT='
"packages have been kept back" usually indicates some dependency issue
that caused apt to not fully upgrade the system.
'
piuparts-0.64ubuntu1/known_problems/overwrite_other_packages_files_error.conf 0000664 0000000 0000000 00000001454 12452567512 025131 0 ustar #
# detect packages which try to overwrite other packages files
#
PATTERN='trying to overwrite (.*) which is also in package'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because they tried to overwrite other packages files'
HELPTEXT='
This is because the package tries to overwrite another packages files without declaring a replaces relation. See policy 7.6 at
https://www.debian.org/doc/debian-policy/ch-relationships.html#s-replaces.
According to the thread started at 200908071233.02813.holger@layer-acht.org these bugs are to be filed with severity serious.
'
piuparts-0.64ubuntu1/known_problems/needs_rebuild_issue.conf 0000664 0000000 0000000 00000001214 12452567512 021457 0 ustar #
# detect packages which have the string "Please rebuild the package" or "package ... should be rebuilt" in their logs
#
PATTERN="Please rebuild the package|should be rebuilt|should be rebuild|warning: maintainer scripts should not call install-info anymore"
WHERE='pass'
ISSUE=1
HEADER='Packages which have logs with the string "Please rebuild the package" or "package ... should be rebuilt"'
HELPTEXT='
This is a recommendation to rebuild some packages with updated debhelper to enable new features, e.g. trigger support.
Please identify the correct package causing this warning and retest the rdepends after that package was fixed.
'
piuparts-0.64ubuntu1/known_problems/unknown_purge_error.conf 0000664 0000000 0000000 00000001074 12452567512 021561 0 ustar #
# detect packages which try to overwrite other packages files
#
PATTERN='ERROR: Command failed .*.dpkg., .--purge., .--pending.]'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because dpkg --purge --pending failed'
HELPTEXT='
This is often because some dependencies have to be removed together and not seperatedly, and thus rather a bug in piuparts... but be careful, this list also includes failures due to "command not found"-error, which made the purge fail... so file those bugs first.
'
piuparts-0.64ubuntu1/known_problems/logrotate_error_after_removal_error.conf 0000664 0000000 0000000 00000001072 12452567512 024775 0 ustar #
# detect packages with logrotate errors after the package has been removed
#
PATTERN='(FAIL: Logrotate file .* has output with package removed|ERROR: Command failed.*'/etc/logrotate\.d/.*'])'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because a logrotate script has output and/or exits with error after the package has been removed'
HELPTEXT='
Most of these packages are probably not buggy but rather affected by #582630. It is being considered to disable this check...
'
piuparts-0.64ubuntu1/known_problems/post_removal_script_error.conf 0000664 0000000 0000000 00000000517 12452567512 022757 0 ustar #
# detect packages which failed because post-removal maintainer script failed
#
PATTERN='subprocess .*post-removal script returned error'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because post-removal maintainer script failed'
HELPTEXT='
This is a somewhat unclassified failure at the moment.
'
piuparts-0.64ubuntu1/known_problems/inadequate_exit_issue.conf 0000664 0000000 0000000 00000000745 12452567512 022034 0 ustar #
# detect packages which have the string "Exit code from adequate was" in their logs
#
PATTERN='(WARN|FAIL): Exit code from adequate was'
WHERE='pass fail bugged affected'
ISSUE=0
HEADER='Packages which have logs with the string "Exit code from adequate was"'
HELPTEXT='
Running adequate resulted in an exit code not equal zero, which indicates a severe problem with adequate. Please investigate and report.
'
piuparts-0.64ubuntu1/known_problems/resource_violation_error.conf 0000664 0000000 0000000 00000000677 12452567512 022603 0 ustar #
# detect packages violating resource limits during the test
#
PATTERN='Command was terminated after exceeding|Process KILLED - exceed maximum run time'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages where the test was aborted after exceeding time or output limit'
HELPTEXT='
Usually caused by seriously misbehaving maintainer scripts that go into endless loops or try to get user input in DEBIAN_FRONTEND=noninteractive mode.
'
piuparts-0.64ubuntu1/known_problems/installs_over_symlink_issue.conf 0000664 0000000 0000000 00000001132 12452567512 023304 0 ustar #
# detect packages which have the string "dirname part contains a symlink" in their logs
#
PATTERN='silently overwrites files via directory symlinks|dirname part contains a symlink'
WHERE='pass'
ISSUE=1
HEADER='Packages that install something over existing symlinks'
HELPTEXT='
Installing anything over a symlink opens a can of worms -
this causes problems on upgrades while switching between directory and symlink
or if the symlink is ever changed.
Piuparts looks at all $pathname known to dpkg and checks for
$(dirname $pathname) != $(readlink $(dirname $pathname))
'
piuparts-0.64ubuntu1/known_problems/disappeared_files_after_purge_error.conf 0000664 0000000 0000000 00000000435 12452567512 024706 0 ustar #
# detect packages with disappeared files after purge
#
PATTERN='FAIL: After purging files have disappeared:'
EXCLUDE_PATTERN=',|usr/local'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with files which disappeared after purge'
HELPTEXT='
This is obviously broken.
'
piuparts-0.64ubuntu1/known_problems/debsums_mismatch_issue.conf 0000664 0000000 0000000 00000000464 12452567512 022210 0 ustar #
# detect packages which modify shipped files
#
PATTERN='FAIL: debsums reports modifications inside the chroot'
WHERE='pass'
ISSUE=1
HEADER='Packages with modified files before removal'
HELPTEXT='
Modifying conffiles is forbidden by Policy 10.7.3.
Modifying other shipped files is a stupid idea.
'
piuparts-0.64ubuntu1/known_problems/boring_broken_symlink_inadequate_issue.conf 0000664 0000000 0000000 00000000754 12452567512 025451 0 ustar #
# detect packages which have the string "Running adequate resulted in less interesting tags found" in their logs
#
PATTERN='(FAIL|WARN): Running adequate resulted in less interesting tags found: .* broken-symlink'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'broken-symlink' by adequate"
HELPTEXT="
Some issues detected by adequate are also detected by piuparts, 'broken-symlink' is one of them.
"
piuparts-0.64ubuntu1/known_problems/unowned_files_after_purge_error.conf 0000664 0000000 0000000 00000001460 12452567512 024103 0 ustar #
# detect packages with unowned files after purge (policy 6.8)
#
PATTERN='not owned'
EXCLUDE_PATTERN='/usr/share/mime/|usr/local/'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with unowned files after purge'
HELPTEXT='
WARNING: this list might contain false positives.
One group of them are packages with files in /usr/share/mime
- those are bugs from shared-mime-info (#527063) and have been ignored for this list.
There are probably others like this as well.
Packages with unowned files after purge (violating policy 6.8) see
https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-removedetails
'
piuparts-0.64ubuntu1/known_problems/unowned_lib_symlink_error.conf 0000664 0000000 0000000 00000000347 12452567512 022735 0 ustar #
# detect unowned symlinks in library directories
#
PATTERN='UNOWNED SYMLINK'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Unowned symlinks is library directories'
HELPTEXT='
These should rather be shipped in packages.
'
piuparts-0.64ubuntu1/known_problems/modified_files_after_purge_error.conf 0000664 0000000 0000000 00000000423 12452567512 024202 0 ustar #
# detect packages with modified files after purge
#
PATTERN='FAIL: After purging files have been modified:'
EXCLUDE_PATTERN=',|usr/local'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with modified files after purge'
HELPTEXT='
This is obviously broken.
'
piuparts-0.64ubuntu1/known_problems/post_installation_script_error.conf 0000664 0000000 0000000 00000000536 12452567512 024014 0 ustar #
# detect packages which failed because post-installation maintainer script failed
#
PATTERN='subprocess .*post-installation script returned error'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because post-installation maintainer script failed'
HELPTEXT='
This is a somewhat unclassified failure at the moment.
'
piuparts-0.64ubuntu1/known_problems/missing_copyright_file_inadequate_issue.conf 0000664 0000000 0000000 00000000702 12452567512 025614 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .*missing-copyright-file|MISSING COPYRIGHT FILE'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'missing-copyright-file' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'missing-copyright-file' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/command_not_found_error.conf 0000664 0000000 0000000 00000001722 12452567512 022351 0 ustar #
# detect packages with miss a depends or use non-essential in purge
#
PATTERN='command not found|: not found'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs with the string "command not found"'
HELPTEXT='
From the third paragraph about the meaning of the depends field in
https://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps
The Depends field should also be used if the postinst, prerm or postrm scripts
require the package to be present in order to run. __Note, however, that the
postrm cannot rely on any non-essential packages to be present during the
purge phase__.
NOTE: it has not been verified that this error really caused the package to
fail the piuparts test, but it did fail.
There are also successful logs with "command not found" (though not listed below).
'
piuparts-0.64ubuntu1/known_problems/missing_md5sums_error.conf 0000664 0000000 0000000 00000000407 12452567512 022005 0 ustar #
# detect packages that ship files without md5sums
#
PATTERN='(FILE WITHOUT MD5SUM|MD5SUM FILE NOT FOUND)'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages containing files without md5sum'
HELPTEXT='
Packages that ship files that have no md5sum.
'
piuparts-0.64ubuntu1/known_problems/owned_files_by_many_packages_error.conf 0000664 0000000 0000000 00000001136 12452567512 024531 0 ustar #
# detect conffiles owned by two or more packages which are not removed by dpkg correctly
#
PATTERN='owned by.+,'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs which have conffiles owned by two or more packages which are not removed by dpkg correctly'
HELPTEXT='
So these might be ok packages (or not, as there might be other problems), but we cannot know until #454694 in dpkg is fixed.
#316521: dpkg: incomplete cleanup of empty directories
'
piuparts-0.64ubuntu1/known_problems/piuparts-depends-dummy_error.conf 0000664 0000000 0000000 00000000500 12452567512 023271 0 ustar #
# detect problems where piuparts-depends-dummy.deb was not installed
#
PATTERN='ERROR: Installation of piuparts-depends-dummy FAILED'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Problems installing piuparts-depends-dummy.deb'
HELPTEXT='
apt chose to remove piuparts-depends-dummy.deb instead of fixing it.
'
piuparts-0.64ubuntu1/known_problems/program_name_collision_inadequate_issue.conf 0000664 0000000 0000000 00000001036 12452567512 025577 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* program-name-collision'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'program-name-collision' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'program-name-collision' which indicates that this package ships a program with the same name as another program. This is a violation of debian-policy 10.1.
"
piuparts-0.64ubuntu1/known_problems/py_file_not_bytecompiled_inadequate_issue.conf 0000664 0000000 0000000 00000000667 12452567512 026135 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* py-file-not-bytecompiled'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'py-file-not-bytecompiled' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'py-file-not-bytecompiled' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/module_build_error_issue.conf 0000664 0000000 0000000 00000000527 12452567512 022536 0 ustar #
# detect dkms module source packages that fail to build for a current kernel
#
PATTERN='Error! Bad return status for module build on kernel'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="DKMS-packages failing to build a module for a default kernel"
HELPTEXT="
Kernel module source may not be compatible with the latest kernel.
"
piuparts-0.64ubuntu1/known_problems/insserv_error.conf 0000664 0000000 0000000 00000002410 12517712417 020342 0 ustar #
# detect packages with fail due to insserv error
#
PATTERN='insserv: exiting now|service.*already provided'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs with the string "insserv: exiting now"'
HELPTEXT='
Some packages fail to install because their init.d scripts have
headers with bugs. There are several classes of bugs.
Some packages
fail to install because the init.d script have conflicting
provide. This is normally reported like this:
insserv: script clvm: service lvm already provided!
insserv: exiting now!
Other packages fail to install because their dependencies are missing.
This is normally reported like this:
insserv: Service portmap has to be enabled to start service quotarpc
insserv: exiting now!
Last, some packages introduce dependency loops, this is normally
reported like this:
insserv: There is a loop between service script1 and script2 if started
insserv: exiting without changing boot order!
See the paragraph "How to solve migration problems" at https://wiki.debian.org/LSBInitScripts/DependencyBasedBoot for information how to fix these issues.
'
piuparts-0.64ubuntu1/known_problems/diversion_error.conf 0000664 0000000 0000000 00000000516 12452567512 020662 0 ustar #
# detect packages which mishandle diversions
#
PATTERN='ERROR: FAIL: (Existing|Installed) diversions'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages that leave a modified diversion state'
HELPTEXT='
Packages need to remove all the diversions they introduced and may not modify diversions setup by other packages.
'
piuparts-0.64ubuntu1/known_problems/boring_obsolete_conffile_inadequate_issue.conf 0000664 0000000 0000000 00000000765 12452567512 026106 0 ustar #
# detect packages which have the string "Running adequate resulted in less interesting tags found" in their logs
#
PATTERN='(FAIL|WARN): Running adequate resulted in less interesting tags found: .* obsolete-conffile'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'obsolete-conffile' by adequate"
HELPTEXT="
Some issues detected by adequate are also detected by piuparts, 'obsolete-conffile' is one of them.
"
piuparts-0.64ubuntu1/known_problems/missing_md5sums_issue.conf 0000664 0000000 0000000 00000000367 12452567512 022011 0 ustar #
# detect packages that ship files without md5sums
#
PATTERN='(FILE WITHOUT MD5SUM|MD5SUM FILE NOT FOUND)'
WHERE='pass'
ISSUE=1
HEADER='Packages containing files without md5sum'
HELPTEXT='
Packages that ship files that have no md5sum.
'
piuparts-0.64ubuntu1/known_problems/obsolete_conffiles_error.conf 0000664 0000000 0000000 00000001007 12452567512 022520 0 ustar #
# detect packages that leave obsolete conffiles after upgrades
#
PATTERN='OBSOLETE CONFFILE'
WHERE='fail bugged affected'
ISSUE=1
HEADER='Packages leaving obsolete conffiles after upgrade'
HELPTEXT='
Packages that leave obsolete conffiles after upgrade.
Using
dpkg-maintscript-helper rm_conffile
via dh_installdeb package.maintscript files is the recommended way to clean them up.
There may be false positives, e.g. if a conffile was converted to a maintainer script managed configuration file.
'
piuparts-0.64ubuntu1/known_problems/debsums_mismatch_error.conf 0000664 0000000 0000000 00000000504 12452567512 022204 0 ustar #
# detect packages which modify shipped files
#
PATTERN='FAIL: debsums reports modifications inside the chroot'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with modified files before removal'
HELPTEXT='
Modifying conffiles is forbidden by Policy 10.7.3.
Modifying other shipped files is a stupid idea.
'
piuparts-0.64ubuntu1/known_problems/pre_removal_script_error.conf 0000664 0000000 0000000 00000000514 12452567512 022555 0 ustar #
# detect packages which failed because pre-removal maintainer script failed
#
PATTERN='subprocess .*pre-removal script returned error'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because pre-removal maintainer script failed'
HELPTEXT='
This is a somewhat unclassified failure at the moment.
'
piuparts-0.64ubuntu1/known_problems/missing_pkgconfig-dependency_issue.conf 0000664 0000000 0000000 00000000675 12536542721 024477 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .*missing-pkgconfig-dependency'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'missing-pkgconfig-dependency' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'missing-pkgconfig-dependency' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/alternatives_after_purge_error.conf 0000664 0000000 0000000 00000001254 12452567512 023744 0 ustar #
# detect packages with unowned files in /etc/alternatives after purge (policy 6.8)
#
PATTERN='/etc/alternatives/.*not owned'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with leftover alternatives after purge'
HELPTEXT='
Packages with unowned files in /etc/alternatives after purge (violating policy 6.8) see
https://www.debian.org/doc/debian-policy/ch-maintainerscripts.html#s-removedetails
Alternatives are usually registered with update-alternatives in postinst configure and need to be unregistered again in prerm remove.
'
piuparts-0.64ubuntu1/known_problems/missing_alternative_inadequate_issue.conf 0000664 0000000 0000000 00000001203 12452567512 025120 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* missing-alternative'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'missing-alternative' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'missing-alternative' which indicates a bug similar to this situation: a package is a provider of the virtual package 'x-terminal-emulator', but it doesn't register itself as an alternative for '/usr/bin/x-terminal-emulator'. See debian-policy 11.8.3 and 11.8.4.
"
piuparts-0.64ubuntu1/known_problems/broken_symlinks_issue.conf 0000664 0000000 0000000 00000001016 12452567512 022064 0 ustar #
# detect packages which have the string "Broken symlinks" in their logs
#
PATTERN='(WARN|FAIL): Broken symlink'
WHERE='pass'
ISSUE=1
HEADER='Packages which have logs with the string "Broken symlinks"'
HELPTEXT='
This is clearly an error, but as there are too many of this kind, piuparts can be configured to not fail if it detects broken symlinks. Another option is not to test for broken symlinks. See the piuparts manpage for details.
'
piuparts-0.64ubuntu1/known_problems/pre_depends_error.conf 0000664 0000000 0000000 00000001427 12452567512 021152 0 ustar #
# detect packages which failed because of a problem with pre-depends
#
PATTERN='E: Couldn.t configure pre-depend .* for .*, probably a dependency cycle.'
WHERE='fail bugged affected'
ISSUE=0
HEADER='Packages with failed logs because of a problem with pre-depends '
HELPTEXT='
The package(s) in question fail(s) to install or upgrade properly, because a pre-dependent package could not be configured. This is likely due to a dependency cycle.
Note that it is possible, that aptitude can deal with (some of) such situations (ie upgrades), (by removing the packages first), while apt-get cannot. While it can be argued this is a problem in apt-get, it is also a problem in the package(s) listed below, as both aptitude and apt-get can be used for installing packages.
'
piuparts-0.64ubuntu1/known_problems/pyshared_file_not_bytecompiled_inadequate_issue.conf 0000664 0000000 0000000 00000000711 12452567512 027312 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* pyshared-file-not-bytecompiled'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'pyshared-file-not-bytecompiled' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'pyshared-file-not-bytecompiled' which indicates a bug.
"
piuparts-0.64ubuntu1/known_problems/library_not_found_inadequate_issue.conf 0000664 0000000 0000000 00000000642 12452567512 024576 0 ustar #
# detect packages with some inadequate tag from adequate
#
PATTERN='(FAIL|WARN): Running adequate resulted in .* library-not-found'
WHERE='pass fail bugged affected'
ISSUE=1
HEADER="Packages tagged 'library-not-found' by adequate"
HELPTEXT="
Running adequate resulted in the package being tagged 'library-not-found' which indicates a bug.
"
piuparts-0.64ubuntu1/CONTRIBUTING 0000664 0000000 0000000 00000002131 12452567511 013365 0 ustar Contributing code to this project
---------------------------------
It's helpful to track fixes or new features via wishlist bugs against the
'piuparts' package, eg with the 'reportbug' tool ('devscripts' package).
The BTS will ensure the developers' mailing list
piuparts-devel@lists.alioth.debian.org
is notified.
Patches can be submitted by mail (git format-patch, see below)
or as requests to pull from a publicly-visible git repository.
In either case, please make a topic branch based on the 'develop' branch.
You can send patches or requests to the development list,
or to the tracking bug: @bugs.debian.org.
One possible workflow:
git clone git://anonscm.debian.org/piuparts/piuparts.git
git checkout origin/develop -b
git commit -a
git format-patch -M origin/develop
reportbug piuparts
Contributing bugs to other projects
-----------------------------------
Another very useful type of contributions are filing bug reports based
on piuparts runs. This is described in https://piuparts.debian.org/bug_howto.html
piuparts-0.64ubuntu1/piuparts_slave_join.8.txt 0000664 0000000 0000000 00000002016 12536542721 016523 0 ustar piuparts_slave_join(8)
======================
:doctype: manpage
:revdate: 2013-05-27
NAME
----
piuparts_slave_join - join a running piuparts-slave screen session
SYNOPSIS
--------
*piuparts_slave_join*
DESCRIPTION
-----------
*piuparts_slave_join* joins a running piuparts-slave session in screen.
OPTIONS
-------
There are no options to this command.
ENVIRONMENT
-----------
Running piuparts in master-slave mode requires configuration in _/etc/piuparts_.
NOTES
-----
Make sure to also read */usr/share/doc/piuparts-master/README_server.txt*.
See *screen*(1) for full instructions on how to navigate between displays. In short:
*Ctrl-A *::
Navigates to display . Slaves are found at screens 1 through 'slave-count', defined in the piuparts configuration file.
*Ctrl-A d*::
Detatch from *screen*. The session can be re-established with *piuparts-slave-join*.
SEE ALSO
--------
*piuparts*(1), *piuparts_slave_run*(8), *screen*(1)
AUTHOR
------
Holger Levsen (holger@layer-acht.org)
// vim: set filetype=asciidoc:
piuparts-0.64ubuntu1/instances/ 0000775 0000000 0000000 00000000000 12536542721 013524 5 ustar piuparts-0.64ubuntu1/instances/piuparts.conf.piu-slave-1und1-01 0000664 0000000 0000000 00000017216 12517712417 021321 0 ustar #
# This is the configuration file for piuparts running in master-slave mode on pejacevic.debian.org (as master) and piu-slave-bm-a.debian.org (as slave).
#
# For more information on this setup see https://anonscm.debian.org/cgit/piuparts/piuparts.git/tree/README_pejacevic.txt
#
[DEFAULT]
# these are needed always
flags-base =
# see https://bugs.debian.org/604807
--skip-logrotatefiles-test
# restrict to problems in the package being tested
--warn-on-others
# default exceptions
--scriptsdir /etc/piuparts/scripts
# pejacevic's slaves are doing everything relevant on a ramdisk anyway
--no-eatmydata
# allow starting database servers
--allow-database
# default flags, only warning on leftover files
flags-default =
%(flags-base)s
--warn-on-leftovers-after-purge
# like default flags, but failing on leftover files
flags-leftovers =
%(flags-base)s
# perform some additional cleanup
--scriptsdir /etc/piuparts/scripts-leftovers
# common flags for tests starting in jessie
flags-start-jessie =
# no flags needed
# common flags for tests ending in jessie
flags-end-jessie =
# extra fake-essential packages for successfully purging in jessie
--scriptsdir /etc/piuparts/scripts-jessie
# debsums failures won't be fixed in jessie, mostly related to
# obsolete/renamed conffiles that moved to different packages
--warn-on-debsums-errors
# common flags for tests starting in wheezy
flags-start-wheezy =
# no flags needed
# common flags for tests ending in wheezy
flags-end-wheezy =
# extra fake-essential packages for successfully purging in wheezy
--scriptsdir /etc/piuparts/scripts-wheezy
# debsums failures won't be fixed in wheezy
--warn-on-debsums-errors
# common flags for tests starting in squeeze
flags-start-squeeze =
# up to squeeze a non-empty /etc/shells was shipped, actually installing
# and removing a shell would remove its entry from /etc/shells
-i /etc/shells
# common flags for tests ending in squeeze
flags-end-squeeze =
# extra fake-essential packages for successfully purging in squeeze
--scriptsdir /etc/piuparts/scripts-squeeze
# debsums failures won't be fixed in squeeze
--warn-on-debsums-errors
# common flags for tests starting in lenny
flags-start-lenny =
# dpkg --force-unsafe-io was added in squeeze
--dpkg-noforce-unsafe-io
# same flags needed as in squeeze
%(flags-start-squeeze)s
[global]
sections =
experimental
sid2experimental
sid
sid-nodoc
testing2sid
jessie
# jessie-proposed
jessie2proposed
wheezy2jessie
wheezy2bpo2jessie
# wheezy-proposed
wheezy2proposed
squeeze2wheezy-proposed
wheezy
squeeze2wheezy
squeeze2bpo-sloppy
squeeze2bpo2wheezy
squeeze2squeeze-lts
squeeze
lenny2squeeze
mirror = http://mirror.1und1.de/debian/
master-host = pejacevic.debian.org
master-user = piupartsm
bts-from = piuparts-devel@lists.alioth.debian.org
master-command = /srv/piuparts.debian.org/share/piuparts/piuparts-master
piuparts-command =
sudo
env PYTHONPATH=%(PYTHONPATH)s
timeout -s INT -k 5m 35m
/srv/piuparts.debian.org/sbin/piuparts
PYTHONPATH = /srv/piuparts.debian.org/lib/python2.7/dist-packages
master-directory = /srv/piuparts.debian.org/master
slave-directory = /srv/piuparts.debian.org/slave
basetgz-directory = /srv/piuparts.debian.org/slave/basetgz
output-directory = /srv/piuparts.debian.org/htdocs
backup-directory = /srv/piuparts.debian.org/backup
tmpdir = /srv/piuparts.debian.org/tmp
doc-root = /
components = main
# the slave-count setting is for the slave(s)
slave-count = 4
# 30*60
idle-sleep = 1800
max-tgz-age = 0
max-reserved = 100
# rescheduling settings
expire-old-days = 120
reschedule-old-days = 90
reschedule-old-count = 250
expire-fail-days = 15
reschedule-fail-days = 10
reschedule-fail-count = 50
reschedule-untestable-days = 2
[experimental]
precedence = 5
piuparts-flags =
%(flags-default)s
distro = experimental
depends-sections = sid
[sid]
precedence = 1
description = + Fails if there are leftover files after purge.
piuparts-flags =
%(flags-leftovers)s
# Once there are no packages left which leave files on purge behind,
# --pedantic-purge-test should be added
distro = sid
# 3 days (60*60*24*3)
max-tgz-age = 259200
[sid-nodoc]
precedence = 100
description = + Testing without files in /usr/share/doc.
piuparts-flags =
%(flags-default)s
--scriptsdir /etc/piuparts/scripts-no-usr-share-doc
distro = sid
[testing2sid]
precedence = 2
piuparts-flags =
%(flags-default)s
distro = testing
upgrade-test-distros = testing sid
reschedule-old-count = 0
[sid2experimental]
precedence = 4
piuparts-flags =
%(flags-default)s
depends-sections = sid
distro = experimental
arch = i386
area = main
upgrade-test-distros = sid experimental
[jessie]
precedence = 3
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
# 1 week (60*60*24*7)
max-tgz-age = 604800
[jessie-proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie-proposed
[jessie2proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
upgrade-test-distros = jessie jessie-proposed
[wheezy2jessie]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2bpo2jessie]
precedence = 5
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
depends-sections = wheezy
arch = i386
area = main
distro = wheezy-backports
upgrade-test-distros = wheezy wheezy-backports jessie
[wheezy]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
# 1 month (60*60*24*30)
max-tgz-age = 2592000
[wheezy-proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy-proposed
[wheezy2proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
upgrade-test-distros = wheezy wheezy-proposed
[squeeze2wheezy-proposed]
precedence = 4
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
distro = squeeze
upgrade-test-distros = squeeze wheezy-proposed
[squeeze2wheezy]
precedence = 4
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
distro = squeeze
upgrade-test-distros = squeeze wheezy
[squeeze2bpo2wheezy]
precedence = 6
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze
arch = i386
area = main
distro = squeeze-backports
upgrade-test-distros = squeeze squeeze-backports wheezy
[squeeze2bpo-sloppy]
precedence = 6
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze squeeze2bpo2wheezy
arch = i386
area = main
upgrade-test-distros = squeeze squeeze-backports-sloppy
[squeeze]
precedence = 7
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze
reschedule-old-count = 0
[squeeze2squeeze-lts]
precedence = 8
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze
arch = i386
area = main
distro = squeeze-lts
upgrade-test-distros = squeeze squeeze-lts
[lenny2squeeze]
precedence = 99
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-squeeze)s
distro = lenny
upgrade-test-distros = lenny squeeze
reschedule-old-count = 0
reschedule-fail-count = 0
piuparts-0.64ubuntu1/instances/piuparts.conf.anbe 0000664 0000000 0000000 00000146233 12517712417 017157 0 ustar #
# This is the configuration file for piuparts in master-slave mode as run by AnBe.
#
[DEFAULT]
flags-base =
--skip-logrotatefiles-test
--warn-on-others
--no-eatmydata
--scriptsdir /etc/piuparts/scripts
--allow-database
flags-default =
%(flags-base)s
--warn-on-leftovers-after-purge
flags-leftovers =
%(flags-base)s
--scriptsdir /etc/piuparts/scripts-leftovers
flags-end-testing =
%(flags-end-stretch)s
flags-start-stable =
%(flags-start-jessie)s
flags-start-stretch =
flags-end-stretch =
flags-start-jessie =
flags-end-jessie =
--scriptsdir /etc/piuparts/scripts-jessie
--warn-on-debsums-errors
flags-start-wheezy =
flags-end-wheezy =
--warn-on-debsums-errors
--scriptsdir /etc/piuparts/scripts-wheezy
flags-start-squeeze =
-i /etc/shells
flags-end-squeeze =
--warn-on-debsums-errors
--scriptsdir /etc/piuparts/scripts-squeeze
flags-start-lenny =
--dpkg-noforce-unsafe-io
%(flags-start-squeeze)s
flags-end-lenny =
--warn-on-debsums-errors
--skip-cronfiles-test
%(flags-end-squeeze)s
-i /etc/udev/
-i /etc/udev/rules.d/
[global]
# sections may be wrapped with continuation lines being indented
# and may contain non-indented comments between continuation lines
basetgz-sections =
tarball/sid/amd64
tarball/sid/i386
tarball/stretch/amd64
tarball/stretch/i386
tarball/jessie/amd64
tarball/jessie/i386
tarball/wheezy/amd64
tarball/wheezy/i386
tarball/squeeze/amd64
tarball/squeeze/i386
tarball/lenny/amd64
tarball/lenny/i386
sections =
experimental/main
sid/main
sid-plus/main
sid-rcmd/main
testing-rcmd/main
testing-nodocs/main
stretch/main
stretch-pu/main
jessie/main
jessie-security/main
jessie-updates/main
jessie-pu/main
jessie-backports/main
wheezy/main
wheezy-rcmd/main
wheezy-proposed/main
wheezy-security/main
wheezy-updates/main
wheezy-pu/main
wheezy-backports/main
sid2experimental/main
testing2sid/main
stable2sid/main
stable2testing2sid/main
jessie2stretch/main
jessie2bpo2stretch/main
wheezy2proposed/main
wheezy2jessie/main
wheezy2jessie-rcmd/main
wheezy2jessie-rcmd_i386/main
wheezy2jessie-sysv/main
wheezy2jessie-apt1st/main
wheezy2bpo2jessie/main
wheezy222testing/main
squeeze222testing/main
lenny222testing/main
#
experimental/contrib
sid/contrib
sid-plus/contrib
sid-rcmd/contrib
testing-rcmd/contrib
testing-nodocs/contrib
stretch/contrib
stretch-pu/contrib
jessie/contrib
jessie-security/contrib
jessie-updates/contrib
jessie-pu/contrib
jessie-backports/contrib
wheezy/contrib
wheezy-rcmd/contrib
wheezy-proposed/contrib
# wheezy-security/contrib
# wheezy-updates/contrib
wheezy-pu/contrib
wheezy-backports/contrib
sid2experimental/contrib
testing2sid/contrib
stable2sid/contrib
stable2testing2sid/contrib
jessie2stretch/contrib
jessie2bpo2stretch/contrib
wheezy2proposed/contrib
wheezy2jessie/contrib
wheezy2jessie-rcmd/contrib
wheezy2jessie-rcmd_i386/contrib
wheezy2jessie-sysv/contrib
wheezy2jessie-apt1st/contrib
wheezy2bpo2jessie/contrib
wheezy222testing/contrib
squeeze222testing/contrib
lenny222testing/contrib
#
experimental/non-free
sid/non-free
sid-plus/non-free
sid-rcmd/non-free
testing-rcmd/non-free
testing-nodocs/non-free
stretch/non-free
stretch-pu/non-free
jessie/non-free
jessie-security/non-free
jessie-updates/non-free
jessie-pu/non-free
jessie-backports/non-free
wheezy/non-free
wheezy-rcmd/non-free
wheezy-proposed/non-free
# wheezy-security/non-free
# wheezy-updates/non-free
wheezy-pu/non-free
wheezy-backports/non-free
sid2experimental/non-free
testing2sid/non-free
stable2sid/non-free
stable2testing2sid/non-free
jessie2stretch/non-free
jessie2bpo2stretch/non-free
wheezy2proposed/non-free
wheezy2jessie/non-free
wheezy2jessie-rcmd/non-free
wheezy2jessie-rcmd_i386/non-free
wheezy2jessie-sysv/non-free
wheezy2jessie-apt1st/non-free
wheezy2bpo2jessie/non-free
wheezy222testing/main
squeeze222testing/non-free
lenny222testing/non-free
#
squeeze/main
squeeze-proposed/main
squeeze-security/main
squeeze-updates/main
squeeze-pu/main
squeeze-lts/main
squeeze-backports/main
squeeze-backports-sloppy/main
squeeze2proposed/main
squeeze2lts2wheezy/main
squeeze2wheezy/main
squeeze2wheezy-rcmd/main
squeeze2wheezy-pu/main
squeeze2bpo2wheezy/main
lenny/main
lenny2squeeze/main
#
squeeze/contrib
squeeze-proposed/contrib
# squeeze-security/contrib
# squeeze-updates/contrib
squeeze-pu/contrib
squeeze-lts/contrib
squeeze-backports/contrib
squeeze-backports-sloppy/contrib
squeeze2proposed/contrib
squeeze2lts2wheezy/contrib
squeeze2wheezy/contrib
squeeze2wheezy-rcmd/contrib
squeeze2wheezy-pu/contrib
squeeze2bpo2wheezy/contrib
lenny/contrib
lenny2squeeze/contrib
#
squeeze/non-free
squeeze-proposed/non-free
# squeeze-security/non-free
# squeeze-updates/non-free
squeeze-pu/non-free
squeeze-lts/non-free
squeeze-backports/non-free
squeeze-backports-sloppy/non-free
squeeze2proposed/non-free
squeeze2lts2wheezy/non-free
squeeze2wheezy/non-free
squeeze2wheezy-rcmd/non-free
squeeze2wheezy-pu/non-free
squeeze2bpo2wheezy/non-free
lenny/non-free
lenny2squeeze/non-free
#
proxy = http://localhost:3128
#
mirror = http://ftp.de.debian.org/debian
#
master-host = localhost
#
master-user = piupartsm
master-command = /srv/piuparts/share/piuparts/piuparts-master
piuparts-command =
sudo
nice
env PYTHONPATH=%(PYTHONPATH)s
timeout -s INT -k 5m 30m
/srv/piuparts/sbin/piuparts
PYTHONPATH = /srv/piuparts/lib/python2.7/dist-packages
master-directory = /srv/piuparts/master
slave-directory = /srv/piuparts/slave
basetgz-directory = /srv/piuparts/slave/basetgz
output-directory = /srv/piuparts/htdocs
backup-directory = /srv/piuparts/backup
tmpdir = /tmp/piupartss
slave-load-max = 9.5
idle-sleep = 1800
max-tgz-age = -1
max-reserved = 50
reschedule-untestable-days = 3
expire-old-days = 135
reschedule-old-days = 120
reschedule-old-count = 250
expire-fail-days = 8
reschedule-fail-days = 5
reschedule-fail-count = 100
############################################################################
### Tarball creation. ###
############################################################################
[tarball/sid/amd64]
piuparts-flags =
%(flags-default)s
distro = None
upgrade-test-distros = sid
arch = amd64
area = main
components = main
# 60*60*24*2
max-tgz-age = 172800
[tarball/sid/i386]
piuparts-flags =
%(flags-default)s
distro = None
upgrade-test-distros = sid
arch = i386
area = main
components = main
# 60*60*24*2
max-tgz-age = 172800
[tarball/stretch/amd64]
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
distro = None
upgrade-test-distros = stretch
arch = amd64
area = main
components = main
# 60*60*24*7
max-tgz-age = 604800
[tarball/stretch/i386]
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
distro = None
upgrade-test-distros = stretch
arch = i386
area = main
components = main
# 60*60*24*7
max-tgz-age = 604800
[tarball/jessie/amd64]
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
distro = None
upgrade-test-distros = jessie
arch = amd64
area = main
components = main
# 60*60*24*30
max-tgz-age = 2592000
[tarball/jessie/i386]
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
distro = None
upgrade-test-distros = jessie
arch = i386
area = main
components = main
# 60*60*24*30
max-tgz-age = 2592000
[tarball/wheezy/amd64]
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
distro = None
upgrade-test-distros = wheezy
arch = amd64
area = main
components = main
# 60*60*24*30
max-tgz-age = 2592000
[tarball/wheezy/i386]
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
distro = None
upgrade-test-distros = wheezy
arch = i386
area = main
components = main
# 60*60*24*30
max-tgz-age = 2592000
[tarball/squeeze/amd64]
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
distro = None
upgrade-test-distros = squeeze
arch = amd64
area = main
components = main
max-tgz-age = 0
[tarball/squeeze/i386]
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
distro = None
upgrade-test-distros = squeeze
arch = i386
area = main
components = main
max-tgz-age = 0
[tarball/lenny/amd64]
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
distro = None
upgrade-test-distros = lenny
arch = amd64
area = main
components = main
max-tgz-age = 0
[tarball/lenny/i386]
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
distro = None
upgrade-test-distros = lenny
arch = i386
area = main
components = main
max-tgz-age = 0
############################################################################
### Install, remove, and purge tests. ###
############################################################################
[experimental/main]
precedence = 40
piuparts-flags =
%(flags-default)s
depends-sections = sid/main
distro = experimental
arch = amd64
area = main
components = main
reschedule-old-days = 30
expire-old-days = 45
[experimental/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
depends-sections = experimental/main sid/main sid/contrib sid/non-free
distro = experimental
arch = amd64
area = contrib
reschedule-old-days = 30
expire-old-days = 45
[experimental/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
depends-sections = experimental/main sid/main sid/contrib sid/non-free
distro = experimental
arch = amd64
area = non-free
reschedule-old-days = 30
expire-old-days = 45
[sid/main]
precedence = 10
piuparts-flags =
%(flags-default)s
distro = sid
arch = amd64
area = main
components = main
reschedule-old-days = 30
expire-old-days = 45
[sid/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
depends-sections = sid/main sid/non-free
distro = sid
arch = amd64
area = contrib
reschedule-old-days = 30
expire-old-days = 45
[sid/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
depends-sections = sid/main sid/contrib
distro = sid
arch = amd64
area = non-free
reschedule-old-days = 30
expire-old-days = 45
[sid-plus/main]
precedence = 30
description = Debian %(distro)s / %(area)s: package installation, removal, installation, removal, and purge test. Failing on leftovers after purge.
piuparts-flags =
--install-remove-install
%(flags-leftovers)s
distro = sid
arch = amd64
area = main
components = main
reschedule-old-days = 60
expire-old-days = 75
[sid-plus/contrib]
precedence = 45
description = Debian %(distro)s / %(area)s: package installation, removal, installation, removal, and purge test. Failing on leftovers after purge.
piuparts-flags =
--install-remove-install
%(flags-leftovers)s
depends-sections = sid-plus/main sid-plus/non-free
distro = sid
arch = amd64
area = contrib
reschedule-old-days = 60
expire-old-days = 75
[sid-plus/non-free]
precedence = 45
description = Debian %(distro)s / %(area)s: package installation, removal, installation, removal, and purge test. Failing on leftovers after purge.
piuparts-flags =
--install-remove-install
%(flags-leftovers)s
depends-sections = sid-plus/main sid-plus/contrib
distro = sid
arch = amd64
area = non-free
reschedule-old-days = 60
expire-old-days = 75
[sid-rcmd/main]
precedence = 30
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
distro = sid
arch = i386
area = main
components = main
reschedule-old-days = 60
expire-old-days = 75
[sid-rcmd/contrib]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
depends-sections = sid-rcmd/main sid-rcmd/non-free
distro = sid
arch = i386
area = contrib
reschedule-old-days = 60
expire-old-days = 75
[sid-rcmd/non-free]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
depends-sections = sid-rcmd/main sid-rcmd/contrib
distro = sid
arch = i386
area = non-free
reschedule-old-days = 60
expire-old-days = 75
[testing-rcmd/main]
precedence = 30
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = testing
arch = i386
area = main
components = main
[testing-rcmd/contrib]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = testing-rcmd/main testing-rcmd/non-free
distro = testing
arch = i386
area = contrib
[testing-rcmd/non-free]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = testing-rcmd/main testing-rcmd/contrib
distro = testing
arch = i386
area = non-free
[testing-nodocs/main]
precedence = 30
description = + Testing without files in /usr/share/doc.
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-no-usr-share-doc
distro = testing
arch = i386
area = main
components = main
[testing-nodocs/contrib]
precedence = 45
description = + Testing without files in /usr/share/doc.
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-no-usr-share-doc
depends-sections = testing-nodocs/main testing-nodocs/non-free
distro = testing
arch = i386
area = contrib
[testing-nodocs/non-free]
precedence = 45
description = + Testing without files in /usr/share/doc.
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-no-usr-share-doc
depends-sections = testing-nodocs/main testing-nodocs/contrib
distro = testing
arch = i386
area = non-free
[stretch/main]
precedence = 10
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
distro = stretch
arch = amd64
area = main
components = main
reschedule-old-days = 60
expire-old-days = 75
[stretch/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
depends-sections = stretch/main stretch/non-free
distro = stretch
arch = amd64
area = contrib
reschedule-old-days = 60
expire-old-days = 75
[stretch/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
depends-sections = stretch/main stretch/contrib
distro = stretch
arch = amd64
area = non-free
reschedule-old-days = 60
expire-old-days = 75
[stretch-pu/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
depends-sections = stretch/main
distro = stretch-proposed-updates
arch = amd64
area = main
components = main
[stretch-pu/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
depends-sections = stretch/main stretch/non-free
distro = stretch-proposed-updates
arch = amd64
area = contrib
[stretch-pu/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
depends-sections = stretch/main stretch/contrib
distro = stretch-proposed-updates
arch = amd64
area = non-free
[jessie/main]
precedence = 10
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
arch = amd64
area = main
components = main
reschedule-old-count = 100
[jessie/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie/non-free
distro = jessie
arch = amd64
area = contrib
[jessie/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie/contrib
distro = jessie
arch = amd64
area = non-free
[jessie-security/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie/updates
arch = amd64
area = main
components = main
[jessie-security/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie/updates
arch = amd64
area = contrib
[jessie-security/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie/updates
arch = amd64
area = non-free
[jessie-updates/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie-updates
arch = amd64
area = main
components = main
[jessie-updates/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie-updates
arch = amd64
area = contrib
[jessie-updates/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie-updates
arch = amd64
area = non-free
[jessie-pu/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie-proposed-updates
arch = amd64
area = main
components = main
[jessie-pu/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie/non-free
distro = jessie-proposed-updates
arch = amd64
area = contrib
[jessie-pu/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie/contrib
distro = jessie-proposed-updates
arch = amd64
area = non-free
[jessie-backports/main]
precedence = 40
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main
distro = jessie-backports
arch = amd64
area = main
components = main
[jessie-backports/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie/non-free jessie-backports/main jessie-backports/non-free
distro = jessie-backports
arch = amd64
area = contrib
[jessie-backports/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie/main jessie-backports/main jessie-backports/contrib
distro = jessie-backports
arch = amd64
area = non-free
[wheezy/main]
precedence = 10
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
arch = amd64
area = main
components = main
reschedule-old-count = 100
[wheezy/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy/non-free
distro = wheezy
arch = amd64
area = contrib
[wheezy/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy/contrib
distro = wheezy
arch = amd64
area = non-free
[wheezy-rcmd/main]
precedence = 40
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
arch = i386
area = main
components = main
reschedule-old-count = 100
[wheezy-rcmd/contrib]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy-rcmd/main wheezy-rcmd/non-free
distro = wheezy
arch = i386
area = contrib
[wheezy-rcmd/non-free]
precedence = 45
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy-rcmd/main wheezy-rcmd/contrib
distro = wheezy
arch = i386
area = non-free
[wheezy-security/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy/updates
arch = amd64
area = main
components = main
[wheezy-security/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy/updates
arch = amd64
area = contrib
[wheezy-security/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy/updates
arch = amd64
area = non-free
[wheezy-updates/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy-updates
arch = amd64
area = main
components = main
[wheezy-updates/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy-updates
arch = amd64
area = contrib
[wheezy-updates/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy-updates
arch = amd64
area = non-free
[wheezy-pu/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy-proposed-updates
arch = amd64
area = main
components = main
[wheezy-pu/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy/non-free
distro = wheezy-proposed-updates
arch = amd64
area = contrib
[wheezy-pu/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy/contrib
distro = wheezy-proposed-updates
arch = amd64
area = non-free
[wheezy-proposed/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy-proposed
arch = amd64
area = main
components = main
reschedule-old-count = 100
[wheezy-proposed/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy-proposed/main wheezy-proposed/non-free
distro = wheezy-proposed
arch = amd64
area = contrib
[wheezy-proposed/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy-proposed/main wheezy-proposed/contrib
distro = wheezy-proposed
arch = amd64
area = non-free
[wheezy-backports/main]
precedence = 40
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main
distro = wheezy-backports
arch = amd64
area = main
components = main
[wheezy-backports/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy/non-free wheezy-backports/main wheezy-backports/non-free
distro = wheezy-backports
arch = amd64
area = contrib
[wheezy-backports/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy/main wheezy-backports/main wheezy-backports/contrib
distro = wheezy-backports
arch = amd64
area = non-free
[squeeze/main]
precedence = 10
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze
arch = amd64
area = main
components = main
reschedule-old-count = 0
[squeeze/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/non-free
distro = squeeze
arch = amd64
area = contrib
reschedule-old-count = 0
[squeeze/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/contrib
distro = squeeze
arch = amd64
area = non-free
reschedule-old-count = 0
[squeeze-security/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze/updates
arch = amd64
area = main
components = main
reschedule-old-count = 0
[squeeze-security/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze/updates
arch = amd64
area = contrib
reschedule-old-count = 0
[squeeze-security/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze/updates
arch = amd64
area = non-free
reschedule-old-count = 0
[squeeze-updates/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-updates
arch = amd64
area = main
components = main
reschedule-old-count = 0
[squeeze-updates/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-updates
arch = amd64
area = contrib
reschedule-old-count = 0
[squeeze-updates/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-updates
arch = amd64
area = non-free
reschedule-old-count = 0
[squeeze-pu/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-proposed-updates
arch = amd64
area = main
components = main
reschedule-old-count = 0
[squeeze-pu/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/non-free
distro = squeeze-proposed-updates
arch = amd64
area = contrib
reschedule-old-count = 0
[squeeze-pu/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/contrib
distro = squeeze-proposed-updates
arch = amd64
area = non-free
reschedule-old-count = 0
[squeeze-lts/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-lts
arch = amd64
area = main
components = main
[squeeze-lts/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/non-free
distro = squeeze-lts
arch = amd64
area = contrib
[squeeze-lts/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze/contrib
distro = squeeze-lts
arch = amd64
area = non-free
[squeeze-proposed/main]
precedence = 20
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze-proposed
arch = amd64
area = main
components = main
reschedule-old-count = 0
[squeeze-proposed/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze-proposed/main squeeze-proposed/non-free
distro = squeeze-proposed
arch = amd64
area = contrib
reschedule-old-count = 0
[squeeze-proposed/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze-proposed/main squeeze-proposed/contrib
distro = squeeze-proposed
arch = amd64
area = non-free
reschedule-old-count = 0
[squeeze-backports/main]
precedence = 40
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main
distro = squeeze-backports
arch = amd64
area = main
components = main
[squeeze-backports/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze-backports/main squeeze-backports/non-free
distro = squeeze-backports
arch = amd64
area = contrib
[squeeze-backports/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze-backports/main squeeze-backports/contrib
distro = squeeze-backports
arch = amd64
area = non-free
[squeeze-backports-sloppy/main]
precedence = 40
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze-backports/main
distro = squeeze-backports-sloppy
arch = amd64
area = main
components = main
[squeeze-backports-sloppy/contrib]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze-backports/main squeeze-backports/non-free
distro = squeeze-backports-sloppy
arch = amd64
area = contrib
[squeeze-backports-sloppy/non-free]
precedence = 45
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze/main squeeze-backports/main squeeze-backports/contrib
distro = squeeze-backports-sloppy
arch = amd64
area = non-free
[lenny/main]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-lenny)s
distro = lenny
arch = amd64
area = main
components = main
reschedule-old-count = 0
[lenny/contrib]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-lenny)s
depends-sections = lenny/main lenny/non-free
distro = lenny
arch = amd64
area = contrib
reschedule-old-count = 0
[lenny/non-free]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-lenny)s
depends-sections = lenny/main lenny/contrib
distro = lenny
arch = amd64
area = non-free
reschedule-old-count = 0
############################################################################
### Install, distupgrade, remove, and purge tests. ###
############################################################################
[lenny2squeeze/main]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-squeeze)s
-i /usr/local/share/octave/
-i /usr/local/share/octave/site-m/
-i /usr/share/octave/ls-R
-i /usr/share/octave/packages/
arch = amd64
area = main
components = main
distro = lenny
upgrade-test-distros = lenny squeeze
reschedule-old-count = 0
[lenny2squeeze/contrib]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-squeeze)s
depends-sections = lenny2squeeze/main lenny2squeeze/non-free
arch = amd64
area = contrib
distro = lenny
upgrade-test-distros = lenny squeeze
reschedule-old-count = 0
[lenny2squeeze/non-free]
precedence = 110
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-squeeze)s
depends-sections = lenny2squeeze/main lenny2squeeze/contrib
arch = amd64
area = non-free
distro = lenny
upgrade-test-distros = lenny squeeze
reschedule-old-count = 0
[lenny222testing/main]
precedence = 120
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-testing)s
arch = amd64
area = main
components = main
distro = lenny
upgrade-test-distros = lenny squeeze wheezy jessie testing
reschedule-old-count = 100
[lenny222testing/contrib]
precedence = 120
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-testing)s
depends-sections = lenny222testing/main lenny222testing/non-free
arch = amd64
area = contrib
distro = lenny
upgrade-test-distros = lenny squeeze wheezy jessie testing
reschedule-old-count = 100
[lenny222testing/non-free]
precedence = 120
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-testing)s
depends-sections = lenny222testing/main lenny222testing/contrib
arch = amd64
area = non-free
distro = lenny
upgrade-test-distros = lenny squeeze wheezy jessie testing
reschedule-old-count = 100
[squeeze2proposed/main]
precedence = 60
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
arch = amd64
area = main
components = main
distro = squeeze
upgrade-test-distros = squeeze squeeze-proposed
reschedule-old-count = 0
[squeeze2proposed/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze2proposed/main squeeze2proposed/non-free
arch = amd64
area = contrib
distro = squeeze
upgrade-test-distros = squeeze squeeze-proposed
reschedule-old-count = 0
[squeeze2proposed/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze2proposed/main squeeze2proposed/contrib
arch = amd64
area = non-free
distro = squeeze
upgrade-test-distros = squeeze squeeze-proposed
reschedule-old-count = 0
[squeeze2lts2wheezy/main]
precedence = 60
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main
distro = squeeze-lts
arch = i386
area = main
components = main
upgrade-test-distros = squeeze squeeze-lts wheezy
[squeeze2lts2wheezy/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main squeeze2lts2wheezy/main squeeze2lts2wheezy/non-free
distro = squeeze-lts
arch = i386
area = contrib
upgrade-test-distros = squeeze squeeze-lts wheezy
[squeeze2lts2wheezy/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main squeeze2lts2wheezy/main squeeze2lts2wheezy/contrib
distro = squeeze-lts
arch = i386
area = non-free
upgrade-test-distros = squeeze squeeze-lts wheezy
[squeeze2wheezy/main]
precedence = 60
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
arch = amd64
area = main
components = main
distro = squeeze
upgrade-test-distros = squeeze wheezy
reschedule-old-count = 100
[squeeze2wheezy/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy/main squeeze2wheezy/non-free
arch = amd64
area = contrib
distro = squeeze
upgrade-test-distros = squeeze wheezy
[squeeze2wheezy/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy/main squeeze2wheezy/contrib
arch = amd64
area = non-free
distro = squeeze
upgrade-test-distros = squeeze wheezy
[squeeze2wheezy-rcmd/main]
precedence = 70
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
arch = amd64
area = main
components = main
distro = squeeze
upgrade-test-distros = squeeze wheezy
reschedule-old-count = 0
[squeeze2wheezy-rcmd/contrib]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy-rcmd/main squeeze2wheezy-rcmd/non-free
arch = amd64
area = contrib
distro = squeeze
upgrade-test-distros = squeeze wheezy
reschedule-old-count = 0
[squeeze2wheezy-rcmd/non-free]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy-rcmd/main squeeze2wheezy-rcmd/contrib
arch = amd64
area = non-free
distro = squeeze
upgrade-test-distros = squeeze wheezy
reschedule-old-count = 0
[squeeze2wheezy-pu/main]
precedence = 60
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy/main wheezy/main
arch = amd64
area = main
components = main
upgrade-test-distros = squeeze wheezy-proposed-updates
reschedule-old-days = 30
expire-old-days = 45
[squeeze2wheezy-pu/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy/main squeeze2wheezy/non-free wheezy/main wheezy/contrib wheezy/non-free
arch = amd64
area = contrib
upgrade-test-distros = squeeze wheezy-proposed-updates
reschedule-old-days = 30
expire-old-days = 45
[squeeze2wheezy-pu/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze2wheezy/main squeeze2wheezy/contrib wheezy/main wheezy/contrib wheezy/non-free
arch = amd64
area = non-free
upgrade-test-distros = squeeze wheezy-proposed-updates
reschedule-old-days = 30
expire-old-days = 45
[squeeze2bpo2wheezy/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main
distro = squeeze-backports
arch = amd64
area = main
components = main
upgrade-test-distros = squeeze squeeze-backports wheezy
[squeeze2bpo2wheezy/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main squeeze2bpo2wheezy/main squeeze2bpo2wheezy/non-free
distro = squeeze-backports
arch = amd64
area = contrib
upgrade-test-distros = squeeze squeeze-backports wheezy
[squeeze2bpo2wheezy/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = squeeze/main squeeze2bpo2wheezy/main squeeze2bpo2wheezy/contrib
distro = squeeze-backports
arch = amd64
area = non-free
upgrade-test-distros = squeeze squeeze-backports wheezy
[squeeze222testing/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-testing)s
arch = amd64
area = main
components = main
distro = squeeze
upgrade-test-distros = squeeze wheezy jessie testing
reschedule-old-count = 100
[squeeze222testing/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-testing)s
depends-sections = squeeze222testing/main squeeze222testing/non-free
arch = amd64
area = contrib
distro = squeeze
upgrade-test-distros = squeeze wheezy jessie testing
reschedule-old-count = 100
[squeeze222testing/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-testing)s
depends-sections = squeeze222testing/main squeeze222testing/contrib
arch = amd64
area = non-free
distro = squeeze
upgrade-test-distros = squeeze wheezy jessie testing
reschedule-old-count = 100
[wheezy2proposed/main]
precedence = 60
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy wheezy-proposed
[wheezy2proposed/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy2proposed/main wheezy2proposed/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy wheezy-proposed
[wheezy2proposed/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
depends-sections = wheezy2proposed/main wheezy2proposed/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy wheezy-proposed
[wheezy2jessie/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = wheezy2jessie/main wheezy2jessie/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
depends-sections = wheezy2jessie/main wheezy2jessie/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd/main]
precedence = 80
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd/contrib]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
depends-sections = wheezy2jessie-rcmd/main wheezy2jessie-rcmd/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd/non-free]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
depends-sections = wheezy2jessie-rcmd/main wheezy2jessie-rcmd/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd_i386/main]
precedence = 80
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
arch = i386
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd_i386/contrib]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
depends-sections = wheezy2jessie-rcmd_i386/main wheezy2jessie-rcmd_i386/non-free
arch = i386
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd_i386/non-free]
precedence = 95
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
depends-sections = wheezy2jessie-rcmd_i386/main wheezy2jessie-rcmd_i386/contrib
arch = i386
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-sysv/main]
precedence = 80
description = + Keeping sysvinit instead of switching to systemd (if possible).
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-sysvinit
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-sysv/contrib]
precedence = 95
description = + Keeping sysvinit instead of switching to systemd (if possible).
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-sysvinit
depends-sections = wheezy2jessie-sysv/main wheezy2jessie-sysv/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-sysv/non-free]
precedence = 95
description = + Keeping sysvinit instead of switching to systemd (if possible).
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-sysvinit
depends-sections = wheezy2jessie-sysv/main wheezy2jessie-sysv/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-apt1st/main]
precedence = 80
description = + Upgrading apt before the rest of the system.
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-apt-first
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-apt1st/contrib]
precedence = 95
description = + Upgrading apt before the rest of the system.
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-apt-first
depends-sections = wheezy2jessie-apt1st/main wheezy2jessie-apt1st/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-apt1st/non-free]
precedence = 95
description = + Upgrading apt before the rest of the system.
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
--scriptsdir /etc/piuparts/scripts-debug-problemresolver
--scriptsdir /etc/piuparts/scripts-apt-first
depends-sections = wheezy2jessie-apt1st/main wheezy2jessie-apt1st/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2bpo2jessie/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
depends-sections = wheezy/main
distro = wheezy-backports
arch = amd64
area = main
components = main
upgrade-test-distros = wheezy wheezy-backports jessie
[wheezy2bpo2jessie/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
depends-sections = wheezy/main wheezy/non-free wheezy2bpo2jessie/main wheezy2bpo2jessie/non-free
distro = wheezy-backports
arch = amd64
area = contrib
upgrade-test-distros = wheezy wheezy-backports jessie
[wheezy2bpo2jessie/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
depends-sections = wheezy/main wheezy2bpo2jessie/main wheezy2bpo2jessie/contrib
distro = wheezy-backports
arch = amd64
area = non-free
upgrade-test-distros = wheezy wheezy-backports jessie
[wheezy222testing/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-testing)s
arch = amd64
area = main
components = main
distro = wheezy
upgrade-test-distros = wheezy jessie testing
reschedule-old-count = 100
[wheezy222testing/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-testing)s
depends-sections = wheezy222testing/main wheezy222testing/non-free
arch = amd64
area = contrib
distro = wheezy
upgrade-test-distros = wheezy jessie testing
reschedule-old-count = 100
[wheezy222testing/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-testing)s
depends-sections = wheezy222testing/main wheezy222testing/contrib
arch = amd64
area = non-free
distro = wheezy
upgrade-test-distros = wheezy jessie testing
reschedule-old-count = 100
[jessie2stretch/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
arch = amd64
area = main
components = main
distro = jessie
upgrade-test-distros = jessie stretch
[jessie2stretch/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
depends-sections = jessie2stretch/main jessie2stretch/non-free
arch = amd64
area = contrib
distro = jessie
upgrade-test-distros = jessie stretch
[jessie2stretch/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
depends-sections = jessie2stretch/main jessie2stretch/contrib
arch = amd64
area = non-free
distro = jessie
upgrade-test-distros = jessie stretch
[jessie2bpo2stretch/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
depends-sections = jessie/main
distro = jessie-backports
arch = amd64
area = main
components = main
upgrade-test-distros = jessie jessie-backports stretch
[jessie2bpo2stretch/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
depends-sections = jessie/main jessie/non-free jessie2bpo2stretch/main jessie2bpo2stretch/non-free
distro = jessie-backports
arch = amd64
area = contrib
upgrade-test-distros = jessie jessie-backports stretch
[jessie2bpo2stretch/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
depends-sections = jessie/main jessie2bpo2stretch/main jessie2bpo2stretch/contrib
distro = jessie-backports
arch = amd64
area = non-free
upgrade-test-distros = jessie jessie-backports stretch
[stable2sid/main]
precedence = 70
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
arch = amd64
area = main
components = main
distro = stable
upgrade-test-distros = stable sid
[stable2sid/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
depends-sections = stable2sid/main stable2sid/non-free
arch = amd64
area = contrib
distro = stable
upgrade-test-distros = stable sid
[stable2sid/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
depends-sections = stable2sid/main stable2sid/contrib
arch = amd64
area = non-free
distro = stable
upgrade-test-distros = stable sid
[stable2testing2sid/main]
precedence = 80
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
arch = amd64
area = main
components = main
distro = stable
upgrade-test-distros = stable testing sid
reschedule-old-count = 0
[stable2testing2sid/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
depends-sections = stable2testing2sid/main stable2testing2sid/non-free
arch = amd64
area = contrib
distro = stable
upgrade-test-distros = stable testing sid
reschedule-old-count = 0
[stable2testing2sid/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
%(flags-start-stable)s
depends-sections = stable2testing2sid/main stable2testing2sid/contrib
arch = amd64
area = non-free
distro = stable
upgrade-test-distros = stable testing sid
reschedule-old-count = 0
[testing2sid/main]
precedence = 60
piuparts-flags =
%(flags-default)s
arch = amd64
area = main
components = main
distro = testing
upgrade-test-distros = testing sid
reschedule-old-count = 0
[testing2sid/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
depends-sections = testing2sid/main testing2sid/non-free
arch = amd64
area = contrib
distro = testing
upgrade-test-distros = testing sid
reschedule-old-count = 0
[testing2sid/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
depends-sections = testing2sid/main testing2sid/contrib
arch = amd64
area = non-free
distro = testing
upgrade-test-distros = testing sid
reschedule-old-count = 0
[sid2experimental/main]
precedence = 70
piuparts-flags =
%(flags-default)s
depends-sections = sid/main
arch = amd64
area = main
components = main
upgrade-test-distros = sid experimental
[sid2experimental/contrib]
precedence = 95
piuparts-flags =
%(flags-default)s
depends-sections = sid2experimental/main sid/main sid/contrib sid/non-free
arch = amd64
area = contrib
upgrade-test-distros = sid experimental
[sid2experimental/non-free]
precedence = 95
piuparts-flags =
%(flags-default)s
depends-sections = sid2experimental/main sid/main sid/contrib sid/non-free
arch = amd64
area = non-free
upgrade-test-distros = sid experimental
piuparts-0.64ubuntu1/instances/README 0000664 0000000 0000000 00000000610 12452567512 014403 0 ustar This directory contains live config files for real instances, usually
with a .$HOSTNAME suffix. These are not intended for being used in
the piuparts Debian packages (or only in /usr/share/doc/.../examples/).
The update-piuparts-(master|slave)-setup scripts (run by piuparts(s|m)) use
them when running and updating an instance directly from GIT.
General config files are placed in ../conf/
piuparts-0.64ubuntu1/instances/piuparts.conf.goldwasser 0000664 0000000 0000000 00000006766 12452567512 020434 0 ustar #
# This is the configuration file for piuparts running in master-slave mode on a (development) host called goldwasser
#
# For more information on this setup see /usr/share/doc/piuparts-master/README_server.txt
#
[DEFAULT]
# these are needed always
flags-base =
# see https://bugs.debian.org/604807
--skip-logrotatefiles-test
# restrict to problems in the package being tested
--warn-on-others
# default exceptions
--scriptsdir /etc/piuparts/scripts
# default flags, only warning on leftover files
flags-default =
%(flags-base)s
--warn-on-leftovers-after-purge
# like default flags, but failing on leftover files
flags-leftovers =
%(flags-base)s
# perform some additional cleanup
--scriptsdir /etc/piuparts/scripts-leftovers
# common flags for starting a test in wheezy
flags-start-wheezy =
# no flags needed
# common flags for tests ending in wheezy
flags-end-wheezy =
# extra fake-essential packages for successfully purging in wheezy
--scriptsdir /etc/piuparts/scripts-wheezy
# debsums failures won't be fixed in wheezy
--warn-on-debsums-errors
# common flags for starting a test in squeeze
flags-start-squeeze =
# eatmydata was added post-squeeze
--no-eatmydata
# up to squeeze a non-empty /etc/shells was shipped, actually installing
# and removing a shell would remove its entry from /etc/shells
-i /etc/shells
# common flags for tests ending in squeeze
flags-end-squeeze =
# extra fake-essential packages for successfully purging in squeeze
--scriptsdir /etc/piuparts/scripts-squeeze
# debsums failures won't be fixed in squeeze
--warn-on-debsums-errors
# common flags for starting a test in lenny
flags-start-lenny =
# dpkg --force-unsafe-io was added in squeeze
--dpkg-noforce-unsafe-io
# same flags needed as in squeeze
%(flags-start-squeeze)s
[global]
sections =
# sid
# jessie
wheezy2jessie
# squeeze
squeeze2squeeze-lts
mirror = http://ftp.de.debian.org/debian/
master-host = goldwasser
master-user = piupartsm
bts-from = piuparts-devel@lists.alioth.debian.org
master-command = /srv/piuparts.debian.org/share/piuparts/piuparts-master
piuparts-command =
timeout -s INT -k 5m 35m
sudo /usr/sbin/piuparts
master-directory = /srv/piuparts.debian.org/master
slave-directory = /srv/piuparts.debian.org/slave
basetgz-directory = /srv/piuparts.debian.org/slave/basetgz
output-directory = /srv/piuparts.debian.org/htdocs
backup-directory = /srv/piuparts.debian.org/backup
tmpdir = /srv/piuparts.debian.org/tmp
doc-root = /piuparts
components = main
# this value is too high for production (it will cause piuparts-slave to sleep
# for a whole day) but useful for testing master-slave mode, for running on a
# test system 24/7 without causing load for 24/7
idle-sleep = 86400
max-reserved = 10
[sid]
description = + Fails if there are leftover files after purge.
piuparts-flags =
%(flags-leftovers)s
distro = sid
arch = amd64
# Once there are no packages left which leave files on purge behind,
# --pedantic-purge-test should be added
[jessie]
piuparts-flags =
%(flags-default)s
distro = jessie
arch = amd64
[wheezy2jessie]
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
arch = amd64
upgrade-test-distros = wheezy jessie
[squeeze]
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze
arch = amd64
reschedule-old-count = 50
[squeeze2squeeze-lts]
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze
area = main
arch = amd64
upgrade-test-distros = squeeze squeeze-lts
piuparts-0.64ubuntu1/instances/piuparts.conf.piu-slave-bm-a 0000777 0000000 0000000 00000000000 12452567512 025423 2piuparts.conf.pejacevic ustar piuparts-0.64ubuntu1/instances/piuparts.conf.lamarr 0000664 0000000 0000000 00000006755 12452567512 017536 0 ustar #
# This is the configuration file for piuparts running in master-slave mode on a (development) host called lamarr
#
# For more information on this setup see /usr/share/doc/piuparts-master/README_server.txt
#
[DEFAULT]
# these are needed always
flags-base =
# see https://bugs.debian.org/604807
--skip-logrotatefiles-test
# restrict to problems in the package being tested
--warn-on-others
# default exceptions
--scriptsdir /etc/piuparts/scripts
# default flags, only warning on leftover files
flags-default =
%(flags-base)s
--warn-on-leftovers-after-purge
# like default flags, but failing on leftover files
flags-leftovers =
%(flags-base)s
# perform some additional cleanup
--scriptsdir /etc/piuparts/scripts-leftovers
# common flags for starting a test in wheezy
flags-start-wheezy =
# no flags needed
# common flags for tests ending in wheezy
flags-end-wheezy =
# extra fake-essential packages for successfully purging in wheezy
--scriptsdir /etc/piuparts/scripts-wheezy
# debsums failures won't be fixed in wheezy
--warn-on-debsums-errors
# common flags for starting a test in squeeze
flags-start-squeeze =
# eatmydata was added post-squeeze
--no-eatmydata
# up to squeeze a non-empty /etc/shells was shipped, actually installing
# and removing a shell would remove its entry from /etc/shells
-i /etc/shells
# common flags for tests ending in squeeze
flags-end-squeeze =
# extra fake-essential packages for successfully purging in squeeze
--scriptsdir /etc/piuparts/scripts-squeeze
# debsums failures won't be fixed in squeeze
--warn-on-debsums-errors
# common flags for starting a test in lenny
flags-start-lenny =
# dpkg --force-unsafe-io was added in squeeze
--dpkg-noforce-unsafe-io
# same flags needed as in squeeze
%(flags-start-squeeze)s
[global]
sections =
# sid
# jessie
wheezy2jessie
# squeeze
squeeze2squeeze-lts
mirror = http://ftp.de.debian.org/debian/
master-host = goldwasser
master-user = piupartsm
bts-from = piuparts-devel@lists.alioth.debian.org
master-command = /srv/piuparts.debian.org/share/piuparts/piuparts-master
piuparts-command =
timeout -s INT -k 5m 35m
sudo /usr/sbin/piuparts
master-directory = /srv/piuparts.debian.org/master
slave-directory = /srv/piuparts.debian.org/slave
basetgz-directory = /srv/piuparts.debian.org/slave/basetgz
output-directory = /srv/piuparts.debian.org/htdocs
backup-directory = /srv/piuparts.debian.org/backup
tmpdir = /srv/piuparts.debian.org/tmp
doc-root = /piuparts
components = main
# this value is too high for production (it will cause piuparts-slave to sleep
# for a whole day) but useful for testing master-slave mode, for running on a
# test system 24/7 without causing load for 24/7
idle-sleep = 86400
max-reserved = 10
[sid]
description = + Fails if there are leftover files after purge.
piuparts-flags =
%(flags-leftovers)s
distro = sid
arch = i386
# Once there are no packages left which leave files on purge behind,
# --pedantic-purge-test should be added
[jessie]
piuparts-flags =
%(flags-default)s
distro = jessie
arch = i386
[wheezy2jessie]
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
arch = i386
upgrade-test-distros = wheezy jessie
[squeeze]
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze
arch = i386
reschedule-old-count = 50
[squeeze2squeeze-lts]
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze
area = main
arch = i386
upgrade-test-distros = squeeze squeeze-lts
piuparts-0.64ubuntu1/instances/piuparts.conf.pejacevic 0000664 0000000 0000000 00000023245 12536542721 020200 0 ustar #
# This is the configuration file for piuparts running in master-slave mode on pejacevic.debian.org (as master) and piu-slave-bm-a.debian.org (as slave).
#
# For more information on this setup see https://anonscm.debian.org/cgit/piuparts/piuparts.git/tree/README_pejacevic.txt
#
[DEFAULT]
# these are needed always
flags-base =
# see https://bugs.debian.org/604807
--skip-logrotatefiles-test
# restrict to problems in the package being tested
--warn-on-others
# default exceptions
--scriptsdir /etc/piuparts/scripts
# pejacevic's slaves are doing everything relevant on a ramdisk anyway
--no-eatmydata
# allow starting database servers
--allow-database
# default flags, only warning on leftover files
flags-default =
%(flags-base)s
--warn-on-leftovers-after-purge
# like default flags, but failing on leftover files
flags-leftovers =
%(flags-base)s
# perform some additional cleanup
--scriptsdir /etc/piuparts/scripts-leftovers
# common flags for tests starting in stretch
flags-start-stretch =
# no flags needed
# common flags for tests ending in stretch
flags-end-stretch =
# no flags needed
# common flags for tests starting in jessie
flags-start-jessie =
# no flags needed
# common flags for tests ending in jessie
flags-end-jessie =
# extra fake-essential packages for successfully purging in jessie
--scriptsdir /etc/piuparts/scripts-jessie
# debsums failures won't be fixed in jessie, mostly related to
# obsolete/renamed conffiles that moved to different packages
--warn-on-debsums-errors
# common flags for tests starting in wheezy
flags-start-wheezy =
# no flags needed
# common flags for tests ending in wheezy
flags-end-wheezy =
# extra fake-essential packages for successfully purging in wheezy
--scriptsdir /etc/piuparts/scripts-wheezy
# debsums failures won't be fixed in wheezy
--warn-on-debsums-errors
# common flags for tests starting in squeeze
flags-start-squeeze =
# up to squeeze a non-empty /etc/shells was shipped, actually installing
# and removing a shell would remove its entry from /etc/shells
-i /etc/shells
# common flags for tests ending in squeeze
flags-end-squeeze =
# extra fake-essential packages for successfully purging in squeeze
--scriptsdir /etc/piuparts/scripts-squeeze
# debsums failures won't be fixed in squeeze
--warn-on-debsums-errors
# common flags for tests starting in lenny
flags-start-lenny =
# dpkg --force-unsafe-io was added in squeeze
--dpkg-noforce-unsafe-io
# same flags needed as in squeeze
%(flags-start-squeeze)s
[global]
basetgz-sections =
tarball/sid
tarball/stretch
tarball/jessie
tarball/wheezy
tarball/squeeze
tarball/lenny
sections =
experimental
sid2experimental
sid
sid-nodoc
testing2sid
stretch
jessie2stretch
jessie
jessie-rcmd
jessie-pu
# jessie-proposed
jessie2proposed
wheezy2jessie
wheezy2jessie-rcmd
wheezy2bpo2jessie
# wheezy-proposed
wheezy2proposed
wheezy
squeeze2wheezy-proposed
squeeze2wheezy
squeeze2bpo-sloppy
squeeze2bpo2wheezy
squeeze2squeeze-lts
squeeze
lenny2squeeze
mirror = http://mirror.bm.debian.org/debian/
master-host = pejacevic.debian.org
master-user = piupartsm
bts-from = piuparts-devel@lists.alioth.debian.org
master-command = /srv/piuparts.debian.org/share/piuparts/piuparts-master
piuparts-command =
sudo
env PYTHONPATH=%(PYTHONPATH)s
timeout -s INT -k 5m 35m
/srv/piuparts.debian.org/sbin/piuparts
PYTHONPATH = /srv/piuparts.debian.org/lib/python2.7/dist-packages
master-directory = /srv/piuparts.debian.org/master
slave-directory = /srv/piuparts.debian.org/slave
basetgz-directory = /srv/piuparts.debian.org/slave/basetgz
output-directory = /srv/piuparts.debian.org/htdocs
backup-directory = /srv/piuparts.debian.org/backup
tmpdir = /srv/piuparts.debian.org/tmp
doc-root = /
components = main
arch = amd64
area = main
# the slave-count setting is for the slave(s)
slave-count = 4
# 30*60
idle-sleep = 1800
max-tgz-age = 0
max-reserved = 100
# rescheduling settings
expire-old-days = 120
reschedule-old-days = 90
reschedule-old-count = 250
expire-fail-days = 15
reschedule-fail-days = 10
reschedule-fail-count = 50
reschedule-untestable-days = 2
[tarball/sid]
piuparts-flags =
%(flags-default)s
distro = None
upgrade-test-distros = sid
# 3 days (60*60*24*3)
max-tgz-age = 259200
[tarball/stretch]
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
distro = None
upgrade-test-distros = stretch
# 1 week (60*60*24*7)
max-tgz-age = 604800
[tarball/jessie]
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
distro = None
upgrade-test-distros = jessie
# 1 month (60*60*24*30)
max-tgz-age = 2592000
[tarball/wheezy]
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
distro = None
upgrade-test-distros = wheezy
# 1 month (60*60*24*30)
max-tgz-age = 2592000
[tarball/squeeze]
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
distro = None
upgrade-test-distros = squeeze
max-tgz-age = 0
[tarball/lenny]
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
distro = None
upgrade-test-distros = lenny
max-tgz-age = 0
[experimental]
precedence = 5
piuparts-flags =
%(flags-default)s
distro = experimental
depends-sections = sid
[sid]
precedence = 1
description = + Fails if there are leftover files after purge.
piuparts-flags =
%(flags-leftovers)s
# Once there are no packages left which leave files on purge behind,
# --pedantic-purge-test should be added
distro = sid
[sid-nodoc]
precedence = 100
description = + Testing without files in /usr/share/doc.
piuparts-flags =
%(flags-default)s
--scriptsdir /etc/piuparts/scripts-no-usr-share-doc
distro = sid
[testing2sid]
precedence = 2
piuparts-flags =
%(flags-default)s
distro = testing
upgrade-test-distros = testing sid
reschedule-old-count = 0
[sid2experimental]
precedence = 4
piuparts-flags =
%(flags-default)s
depends-sections = sid
distro = experimental
upgrade-test-distros = sid experimental
[stretch]
precedence = 3
piuparts-flags =
%(flags-default)s
%(flags-start-stretch)s
%(flags-end-stretch)s
distro = stretch
[jessie2stretch]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-stretch)s
distro = jessie
upgrade-test-distros = jessie stretch
[jessie]
precedence = 3
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
[jessie-rcmd]
precedence = 10
json-sections = none
description = + With recommended packages.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
[jessie-pu]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
depends-sections = jessie
distro = jessie-proposed-updates
[jessie-proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie-proposed
[jessie2proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-jessie)s
%(flags-end-jessie)s
distro = jessie
upgrade-test-distros = jessie jessie-proposed
[wheezy2jessie]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2jessie-rcmd]
precedence = 10
description = + Testing with --install-recommends.
piuparts-flags =
--install-recommends
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
-i /usr/lib/dbus-1.0/dbus-daemon-launch-helper
distro = wheezy
upgrade-test-distros = wheezy jessie
[wheezy2bpo2jessie]
precedence = 5
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-jessie)s
depends-sections = wheezy
distro = wheezy-backports
upgrade-test-distros = wheezy wheezy-backports jessie
[wheezy]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
[wheezy-proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy-proposed
[wheezy2proposed]
precedence = 3
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-wheezy)s
%(flags-end-wheezy)s
distro = wheezy
upgrade-test-distros = wheezy wheezy-proposed
[squeeze2wheezy-proposed]
precedence = 4
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
distro = squeeze
upgrade-test-distros = squeeze wheezy-proposed
[squeeze2wheezy]
precedence = 4
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
distro = squeeze
upgrade-test-distros = squeeze wheezy
[squeeze2bpo2wheezy]
precedence = 6
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-wheezy)s
depends-sections = squeeze
distro = squeeze-backports
upgrade-test-distros = squeeze squeeze-backports wheezy
[squeeze2bpo-sloppy]
precedence = 6
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze squeeze2bpo2wheezy
upgrade-test-distros = squeeze squeeze-backports-sloppy
[squeeze]
precedence = 7
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
distro = squeeze
reschedule-old-count = 0
[squeeze2squeeze-lts]
precedence = 8
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-squeeze)s
%(flags-end-squeeze)s
depends-sections = squeeze
distro = squeeze-lts
upgrade-test-distros = squeeze squeeze-lts
[lenny2squeeze]
precedence = 99
json-sections = none
piuparts-flags =
%(flags-default)s
%(flags-start-lenny)s
%(flags-end-squeeze)s
distro = lenny
upgrade-test-distros = lenny squeeze
reschedule-old-count = 0
reschedule-fail-count = 0
piuparts-0.64ubuntu1/README_pejacevic.txt 0000664 0000000 0000000 00000014146 12452567511 015253 0 ustar Notes about the piuparts installation on pejacevic.debian.org and it's slave(s)
===============================================================================
This document describes the setup for https://piuparts.debian.org - it's used
for reference for the Debian System Administrators (DSA) as well as a guide
for other setting up a similar system, with the piuparts source code
installed from git. For regular installations we recommend to use the
piuparts-master and piuparts-slaves packages as described in
/usr/share/doc/piuparts-master/README_server.txt
== Installation
piuparts.debian.org is a setup running on several systems:
pejacevic.debian.org, running the piuparts-master instance and an apache
webserver to display the results and piu-slave-bm-a.debian.org, running
four piuparts-slave nodes. Not yet in operation there is another,
piu-slave-1und1-01.debian.org, which soon shall go into operation...
=== piuparts installation from source
* basically, apt-get build-dep piuparts - in reality both systems get their
package configuration from git.debian.org/git/mirror/debian.org.git
* pejacevic runs a webserver as well (see below for apache configuration)
* Copy 'https://anonscm.debian.org/cgit/piuparts/piuparts.git/tree/update-piuparts-master-setup?h=develop'
and 'https://anonscm.debian.org/cgit/piuparts/piuparts.git/tree/update-piuparts-slave-setup?h=develop'
to the hosts which should be master and slave. (It's possible and has been
done for a long time to run them on the same host.(
Run the scripts as the piupartsm and piupartss users and clone that git
repository into '/srv/piuparts.debian.org/src' in the first place. Then
checkout the develop branch.
* Ideally provide '/srv/piuparts.debian.org/tmp' on (a sufficiently large)
tmpfs.
* `sudo ln -s /srv/piuparts.debian.org/etc/piuparts /etc/piuparts`
* See below for further user setup instructions.
=== User setup
On pejacevic the piuparts-master user piupartsm needs to be created, on
piu-slave-bm-a a piupartss user is needed for the slave.
Both are members of the group piuparts and '/srv/piuparts.debian.org' needs to
be chmod 2775 and chown piuparts(sm):piuparts.
==== '~/bashrc' for piupartsm and piupartss
Do this for the piupartsm user on pejacevic and piupartss on the slave(s):
----
piupartsm@pejacevic$ cat >> ~/.bashrc <<-EOF
# added manually for piuparts
umask 0002
export PATH="~/bin:\$PATH"
EOF
----
==== set up ssh pubkey authentification
Then create an SSH keypair for piupartss and put it into
'/etc/ssh/userkeys/piupartsm' on pejacevic, so the piupartss user can login
with ssh and run only piuparts-master. Restrict it like this:
----
$ cat /etc/ssh/userkeys/piupartsm
command="/srv/piuparts.debian.org/share/piuparts/piuparts-master",from="2001:41c8:1000:21::21:7,5.153.231.7",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa ...
----
=== Setup sudo for the slave(s)
This is actually done by DSA:
==== '/etc/sudoers' for piu-slave-bm-a and piu-slave-1und1-01
----
# The piuparts slave needs to handle chroots.
piupartss ALL = NOPASSWD: /usr/sbin/piuparts *, \
/bin/umount /srv/piuparts.debian.org/tmp/tmp*, \
/usr/bin/test -f /srv/piuparts.debian.org/tmp/tmp*, \
/usr/bin/rm -rf --one-file-system /srv/piuparts.debian.org/tmp/tmp*
----
=== Apache configuration
Any other webserver will do but apache is used on pejacevic (and maintained by DSA):
----
ServerName piuparts.debian.org
ServerAdmin debian-admin@debian.org
ErrorLog /var/log/apache2/piuparts.debian.org-error.log
CustomLog /var/log/apache2/piuparts.debian.org-access.log combined
DocumentRoot /srv/piuparts.debian.org/htdocs
AddType text/plain .log
AddDefaultCharset utf-8
HostnameLookups Off
UseCanonicalName Off
ServerSignature On
UserDir disabled
# vim:set syn=apache:
----
== Running piuparts
=== Updating the piuparts installation
Updating the master, pejacevic.debian.org:
----
holger@pejacevic~$ sudo su - piupartsm update-piuparts-master-setup develop origin
----
Updating the slave(s), for example on piu-slave-bm-a.debian.org:
----
holger@piu-slave-bm-a~$ sudo su - piupartss update-piuparts-slave-setup develop origin
----
=== Running piuparts
When running piuparts in master/slave mode, the master is never run by itself,
instead it is always started by the slave(s).
==== Starting and stopping the slaves
Run the following script under *your* user account to start four instances of
piuparts-slave on pejacevic, piuparts-master will be started automatically by
the slaves.
----
holger@piu-slave-bm-a:~$ sudo -u piupartss -i slave_run
----
There are several cronjobs installed via '~piupartsm/crontab' and
'~piupartss/crontab') to monitor both master and slave as well as the hosts
they are running on.
It's possible to kill a slave any time by pressing Ctrl-C.
Pressing Ctrl-C once will wait for the current test to finish,
pressing twice will abort the currently running test (which will be redone).
Clean termination may take some time and can be aborted by a third Ctrl-C,
but that may leave temporary directories and processes around.
See the 'piuparts_slave_run (8)' manpage for more information on 'slave_run'.
==== Joining an existing slave session
Run the following script under *your* user account:
----
holger@pejacevic:~$ sudo -u piupartss -i slave_join
----
See the 'piuparts_slave_join (8)' manpage for more information on 'slave_join'.
=== Generating reports for the website
'piuparts-report' is run daily at midnight and at noon from
'~piupartsm/crontab' on pejacevic.
=== Cronjobs to aid problem spotting
Some cronjobs to aid problem spotting reside in '~piupartsm/bin/' and are run
daily by '~piupartsm/crontab'.
- 'detect_network_issues' should detect failed piuparts runs due to network
issues on the host.
- 'detect_stale_mounts' should detect stale mountpoints (usually of /proc)
from failed piuparts runs.
More checks should be added as we become aware of them.
== Authors
Last updated: October 2014
Holger Levsen
// vim: set filetype=asciidoc:
piuparts-0.64ubuntu1/custom-scripts/ 0000775 0000000 0000000 00000000000 12517712417 014534 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-debug-prerm/ 0000775 0000000 0000000 00000000000 12452567511 020433 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-debug-prerm/pre_remove_prerm_set-x 0000775 0000000 0000000 00000000560 12452567511 025052 0 ustar #!/bin/sh
set -e
for target in ${PIUPARTS_OBJECTS%%=*}
do
pkg=${target}
prerm=/var/lib/dpkg/info/$pkg.prerm
if [ -f $prerm ]; then
if head -n 1 $prerm | grep -qE '/bin/(ba)?sh' ; then
echo "DEBUG PRERM REMOVE: enabling 'set -x' in $pkg.prerm"
sed -i '2 i set -x' $prerm
else
echo "Unsupported script type in $prerm:"
head -n 1 $prerm
fi
fi
done
piuparts-0.64ubuntu1/custom-scripts/scripts-debug-purge/ 0000775 0000000 0000000 00000000000 12452567511 020430 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-debug-purge/post_remove_postrm_set-x 0000775 0000000 0000000 00000000570 12452567511 025446 0 ustar #!/bin/sh
set -e
for target in ${PIUPARTS_OBJECTS%%=*}
do
pkg=${target}
postrm=/var/lib/dpkg/info/$pkg.postrm
if [ -f $postrm ]; then
if head -n 1 $postrm | grep -qE '/bin/(ba)?sh' ; then
echo "DEBUG POSTRM PURGE: enabling 'set -x' in $pkg.postrm"
sed -i '2 i set -x' $postrm
else
echo "Unsupported script type in $postrm:"
head -n 1 $postrm
fi
fi
done
piuparts-0.64ubuntu1/custom-scripts/scripts-squeeze/ 0000775 0000000 0000000 00000000000 12517712417 017702 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-squeeze/post_remove_exceptions_squeeze 0000775 0000000 0000000 00000000610 12517712417 026171 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case "$PIUPARTS_DISTRIBUTION" in
squeeze) : ;;
*) exit 0 ;;
esac
case ${PIUPARTS_OBJECTS%%=*} in
libblkid-dev)
#775350 - unhandled symlink to directory conversion
if [ ! -f /usr/share/doc/libblkid1/copyright ]; then
log_debug
apt-get install --reinstall libblkid1
fi
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-squeeze/post_distupgrade_squeeze-fake-essential 0000775 0000000 0000000 00000000505 12452567511 027643 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_DISTRIBUTION" = "squeeze" || exit 0
case ${PIUPARTS_OBJECTS%%=*} in
kmplayer-plugin|kde-core|konqueror|konq-plugins|kwin-baghira|mozart-doc|smb4k|strigi-applet|texlive-full)
# work around #601961: apt: wrongly thinks install-info is essential
apt-get -y install install-info
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-squeeze/post_remove_exceptions_lenny 0000775 0000000 0000000 00000000570 12452567511 025643 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case "$PIUPARTS_DISTRIBUTION" in
lenny) : ;;
*) exit 0 ;;
esac
case ${PIUPARTS_OBJECTS%%=*} in
postgis)
#WORKSAROUND #560409: postgis can't be purged if postgresql
# is not installed due to missing directory
log_debug
mkdir -p /usr/lib/postgresql/8.3/lib
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-squeeze/post_setup_squeeze-fake-essential 0000775 0000000 0000000 00000003155 12517712417 026473 0 ustar #!/bin/sh
set -e
# The following issues won't be fixed in squeeze:
# - unconditional use of deluser during postrm purge
# - unconditional use of ucf during postrm purge
# so add these packages to the "fake" essential set.
USED_DURING_PURGE="adduser ucf"
FAILS_TO_REMOVE=
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# don't install fake essential packages while creating the tarball
exit 0
;;
adduser|ucf)
# allow testing of the fake essential packages
exit 0
;;
gosa-desktop|kde-core|kde-full|kde-plasma-desktop|kde-standard|kdebase-apps|konqueror|konq-plugins|mozart-doc|texlive-full)
# work around #601961: apt: wrongly thinks install-info is essential
case ${PIUPARTS_DISTRIBUTION} in
squeeze|squeeze-proposed|squeeze-lts)
FAILS_TO_REMOVE="$FAILS_TO_REMOVE install-info"
;;
esac
;;
docbookwiki)
USED_DURING_PURGE="$USED_DURING_PURGE mysql-client"
;;
phpbb3)
USED_DURING_PURGE="$USED_DURING_PURGE dbconfig-common"
;;
prelude-manager)
#WORKSAROUND #660455
USED_DURING_PURGE="$USED_DURING_PURGE dbconfig-common"
;;
drupal6|moodle|moodle-book|moodle-debian-edu-theme|scuttle)
if [ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
USED_DURING_PURGE="$USED_DURING_PURGE wwwconfig-common"
fi
;;
octave-audio|octave-symbolic|octave-vrml)
if [ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
USED_DURING_PURGE="$USED_DURING_PURGE octave3.0"
fi
;;
ttf-beteckna)
#502707
if [ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
USED_DURING_PURGE="$USED_DURING_PURGE defoma"
fi
;;
esac
echo "*** Adding fake essential packages ***"
apt-get install -yf $USED_DURING_PURGE $FAILS_TO_REMOVE
piuparts-0.64ubuntu1/custom-scripts/scripts-wheezy/ 0000775 0000000 0000000 00000000000 12452567511 017535 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-wheezy/post_setup_wheezy-fake-essential 0000775 0000000 0000000 00000001046 12452567511 026155 0 ustar #!/bin/sh
set -e
# The following issues won't be fixed in wheezy:
# - unconditional use of deluser during postrm purge
# - unconditional use of ucf during postrm purge
# so add these packages to the "fake" essential set.
USED_DURING_PURGE="adduser ucf"
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# don't install fake essential packages while creating the tarball
exit 0
;;
adduser|ucf)
# allow testing of the fake essential packages
exit 0
;;
esac
echo "*** Adding fake essential packages ***"
apt-get install -yf $USED_DURING_PURGE
piuparts-0.64ubuntu1/custom-scripts/scripts-wheezy/pre_distupgrade_wheezy 0000775 0000000 0000000 00000004164 12452567511 024244 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
# Work around bug where apt/squeeze prefers to 'keep back' some
# upgradable packages instead of removing some obsolete ones.
FORCEREMOVE=
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "wheezy" ] || \
[ "$PIUPARTS_DISTRIBUTION_NEXT" = "wheezy-proposed" ]
then
case ${PIUPARTS_OBJECTS%%=*} in
gnustep|\
gnustep-games|\
gnustep-back0.18-cairo|\
gnustep-back0.18-art|\
gnustep-back-dbg|\
libgnustep-base1.20-dbg|\
addressmanager.app|\
biococoa.app|\
easydiff.app|\
gnumail.app|\
gnumail.app-dbg|\
mines.app|\
projectmanager.app|\
INVALID)
FORCEREMOVE="libobjc2"
;;
libahven17.0|\
libalog0.3-full|\
libalog1-full-dev|\
libalog-full-dbg|\
libapq3.0|\
libapq-postgresql3.0|\
libaws2.7|\
libaws2.7-dev|\
libaws-dbg|\
libflorist2009|\
libflorist-dbg|\
libgmpada1|\
libgmpada1-dbg|\
libgnomeada2.14.2|\
libgnomeada2.14.2-dbg|\
libgnomeada2.14.2-dev|\
libgtkada2.14.2|\
libgtkada2.14.2-dbg|\
libgtkada2.14.2-dev|\
libgtkada-gl2.14.2|\
libgtkada-glade2.14.2|\
libgtkada2-bin|\
liblog4ada0|\
liblog4ada-dbg|\
libnarval1.10.1|\
libnarval1-dev|\
libnarval-dbg|\
libpcscada0.6|\
libplplot-ada|\
libplplot-dev|\
libpolyorb2|\
libtemplates-parser11.5|\
libtexttools4|\
libtexttools4-dbg|\
libtexttools-doc|\
libxmlada3.2|\
libxmlezout0|\
libxmlezout-dbg|\
cl-plplot|\
gprbuild|\
narval-doc|\
narval-generic-actors|\
narval-servers|\
narval-tests-actors|\
narval-utils|\
polyorb-servers|\
INVALID)
FORCEREMOVE="gnat-4.4-base"
;;
dolfin-bin|\
dolfin-dev|\
dolfin-doc|\
petsc-dev|\
python-dolfin|\
INVALID)
# only affects i386
FORCEREMOVE="libjpeg62-dev"
;;
science-physics)
# #706111
FORCEREMOVE="tessa"
;;
firestarter|\
gnome-netstatus-applet|\
gnome-utils|\
INVALID)
FORCEREMOVE="gconf2"
;;
esac
fi
if [ -n "$FORCEREMOVE" ];
then
if dpkg-query -s $FORCEREMOVE >/dev/null 2>&1 ; then
log_debug
echo "Forcibly removing $FORCEREMOVE for smoother upgrade"
dpkg -r --force-depends $FORCEREMOVE
fi
fi
piuparts-0.64ubuntu1/custom-scripts/scripts-unused-examples/ 0000775 0000000 0000000 00000000000 12452567511 021341 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-unused-examples/post_chroot_unpack_key_setup 0000775 0000000 0000000 00000000541 12452567511 027263 0 ustar #!/bin/sh
# we rely on wget being available, make sure to use "--include=wget" in your deboostrap cmdline
echo "Setting up https://example.com/internal_key.asc for apt-get usage."
wget -O - 'https://example.com/internal_key.asc' | apt-key add -
echo "Running apt-get update to have a verified and working Debian repository available."
apt-get update
piuparts-0.64ubuntu1/custom-scripts/scripts-jessie/ 0000775 0000000 0000000 00000000000 12452567511 017504 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-jessie/post_setup_jessie-fake-essential 0000775 0000000 0000000 00000001332 12452567511 026071 0 ustar #!/bin/sh
set -e
# The following issues won't be fixed in jessie:
# - unconditional use of ucf during postrm purge
# so add these packages to the "fake" essential set.
USED_DURING_PURGE="ucf"
# For purging configuration from /var/lib/systemd/
INITSYSTEMHELPERS="init-system-helpers"
case ${PIUPARTS_DISTRIBUTION} in
lenny*|squeeze*|wheezy*)
# package does not exist
INITSYSTEMHELPERS=""
;;
esac
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# don't install fake essential packages while creating the tarball
exit 0
;;
ucf|init-system-helpers)
# allow testing of the fake essential packages
exit 0
;;
esac
echo "*** Adding fake essential packages ***"
apt-get install -yf $USED_DURING_PURGE $INITSYSTEMHELPERS
piuparts-0.64ubuntu1/custom-scripts/scripts-debug-packagemanager/ 0000775 0000000 0000000 00000000000 12452567511 022234 5 ustar ././@LongLink 0000644 0000000 0000000 00000000146 00000000000 011604 L ustar root root piuparts-0.64ubuntu1/custom-scripts/scripts-debug-packagemanager/pre_distupgrade_debug_packagemanager piuparts-0.64ubuntu1/custom-scripts/scripts-debug-packagemanager/pre_distupgrade_debug_packagemanage0000775 0000000 0000000 00000000340 12452567511 031332 0 ustar #!/bin/sh
set -e
if [ ! -f /etc/apt/apt.conf.d/piuparts-debug-packagemanager ]
then
echo "Enabling Debug::pkgPackageManager"
echo 'Debug::pkgPackageManager "true";' >> /etc/apt/apt.conf.d/piuparts-debug-packagemanager
fi
piuparts-0.64ubuntu1/custom-scripts/scripts-debug-problemresolver/ 0000775 0000000 0000000 00000000000 12452567511 022530 5 ustar ././@LongLink 0000644 0000000 0000000 00000000150 00000000000 011577 L ustar root root piuparts-0.64ubuntu1/custom-scripts/scripts-debug-problemresolver/pre_distupgrade_debug_problemresolver piuparts-0.64ubuntu1/custom-scripts/scripts-debug-problemresolver/pre_distupgrade_debug_problemresol0000775 0000000 0000000 00000000520 12452567511 031567 0 ustar #!/bin/sh
set -e
if [ ! -f /etc/apt/apt.conf.d/piuparts-debug-problemresolver ]
then
echo "Enabling Debug::pkgProblemResolver"
echo 'Debug::pkgProblemResolver "true";' >> /etc/apt/apt.conf.d/piuparts-debug-problemresolver
echo 'Debug::pkgProblemResolver::ShowScores "true";' >> /etc/apt/apt.conf.d/piuparts-debug-problemresolver
fi
piuparts-0.64ubuntu1/custom-scripts/scripts-debug-problemresolver/pre_install_debug_problemresolver 0000775 0000000 0000000 00000000575 12452567511 031451 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_TEST" = "install" || exit 0
if [ ! -f /etc/apt/apt.conf.d/piuparts-debug-problemresolver ]
then
echo "Enabling Debug::pkgProblemResolver"
echo 'Debug::pkgProblemResolver "true";' >> /etc/apt/apt.conf.d/piuparts-debug-problemresolver
echo 'Debug::pkgProblemResolver::ShowScores "true";' >> /etc/apt/apt.conf.d/piuparts-debug-problemresolver
fi
piuparts-0.64ubuntu1/custom-scripts/scripts-apt-first/ 0000775 0000000 0000000 00000000000 12517712417 020132 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-apt-first/pre_distupgrade_zz_apt_first 0000775 0000000 0000000 00000000070 12517712417 026034 0 ustar #!/bin/sh
set -e
apt-get update
apt-get -y install apt
piuparts-0.64ubuntu1/custom-scripts/scripts-leftovers/ 0000775 0000000 0000000 00000000000 12517712417 020232 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-leftovers/post_remove_cleanup 0000775 0000000 0000000 00000000437 12452567511 024236 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
dovecot-core)
# #330519 - does not remove certificates on purge
log_debug
rm -fv /etc/dovecot/dovecot.pem /etc/dovecot/private/dovecot.pem
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-leftovers/post_setup_fake-essential 0000775 0000000 0000000 00000001565 12452567511 025350 0 ustar #!/bin/sh
set -e
# If dbconfig-common was already purged, packages that have used
# dbconfig-common in postinst will leave configuration files in
# /etc/dbconfig-common
DBCONFIG="dbconfig-common"
# For purging configuration from /var/lib/systemd/
INITSYSTEMHELPERS="init-system-helpers"
case ${PIUPARTS_DISTRIBUTION} in
lenny*|squeeze*|wheezy*)
# package does not exist
INITSYSTEMHELPERS=""
;;
esac
# openssl may be used during purge to compute the hash for a
# certificate, otherwise files in /etc/ssl/certs can't be removed.
OPENSSL=""
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# skip while creating the tarball
exit 0
;;
dbconfig-common|init-system-helpers)
# allow testing of the fake essential packages
exit 0
;;
stone)
OPENSSL="openssl"
;;
esac
echo "*** Adding fake essential packages ***"
apt-get install -yf $DBCONFIG $INITSYSTEMHELPERS $OPENSSL
piuparts-0.64ubuntu1/custom-scripts/scripts-leftovers/post_purge_manual_cleanup 0000775 0000000 0000000 00000001023 12517712417 025407 0 ustar #!/bin/sh
set -e
log_debug()
{
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
remove_ssl_cert()
{
for c in /etc/ssl/certs/*.0 ; do
if [ -L "$c" ] && [ "$(readlink "$c")" = "$1" ]; then
rm -fv "$c"
fi
done
rm -fv /etc/ssl/certs/$1
rmdir --ignore-fail-on-non-empty /etc/ssl/certs
}
case ${PIUPARTS_OBJECTS%%=*} in
uw-imapd)
log_debug
remove_ssl_cert imapd.pem
;;
ipopd)
log_debug
remove_ssl_cert ipop3d.pem
;;
smartlist)
log_debug
rm -fv /etc/aliases.????-??-??.??:??:??
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-leftovers/pre_remove_preseed_cleanup 0000775 0000000 0000000 00000005043 12517712417 025543 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
dbconfig_enable_purge()
{
log_debug
echo "$1 $1${2+/$2}/dbconfig-remove boolean true" | debconf-set-selections
echo "$1 $1${2+/$2}/purge boolean true" | debconf-set-selections
}
#
# enable extended purge mode that is available in some packages
# but disabled by default because it might remove valuable user or
# application data
#
case ${PIUPARTS_OBJECTS%%=*} in
cvsd)
log_debug
echo "cvsd cvsd/remove_chroot boolean true" | debconf-set-selections
;;
docbookwiki)
log_debug
echo "docbookwiki docbookwiki/purge_books boolean true" | debconf-set-selections
;;
ifetch-tools)
log_debug
echo "ifetch-tools ifetch-tools/purge boolean true" | debconf-set-selections
;;
mlmmj) #668752
log_debug
echo "mlmmj mlmmj/remove-on-purge boolean true" | debconf-set-selections
;;
pluxml)
log_debug
echo "pluxml pluxml/system/purgedata boolean true" | debconf-set-selections
;;
ironic-common)
dbconfig_enable_purge ironic-common
;;
movabletype-opensource)
dbconfig_enable_purge movabletype-opensource
;;
nova-common)
dbconfig_enable_purge nova-common
;;
otrs2)
dbconfig_enable_purge otrs2
;;
pdns-backend-sqlite)
dbconfig_enable_purge pdns-backend-sqlite
;;
pdns-backend-sqlite3)
dbconfig_enable_purge pdns-backend-sqlite3
;;
redmine)
dbconfig_enable_purge redmine instances/default
;;
request-tracker3.8)
dbconfig_enable_purge request-tracker3.8
;;
request-tracker4)
dbconfig_enable_purge request-tracker4
;;
esac
if [ -d /var/lib/mysql ]; then
log_debug
echo "Enabling MySQL database purge."
echo "mysql-server-5.1 mysql-server-5.1/postrm_remove_databases boolean true" | debconf-set-selections
echo "mysql-server-5.5 mysql-server-5.5/postrm_remove_databases boolean true" | debconf-set-selections
echo "mysql-server-5.6 mysql-server-5.6/postrm_remove_databases boolean true" | debconf-set-selections
echo "mariadb-server-10.0 mysql-server-10.0/postrm_remove_databases boolean true" | debconf-set-selections
echo "percona-xtradb-cluster-server-5.5 mysql-server-5.1/postrm_remove_databases boolean true" | debconf-set-selections
fi
if [ -d /var/lib/ldap ]; then
log_debug
echo "Enabling LDAP database purge."
echo "slapd slapd/purge_database boolean true" | debconf-set-selections
fi
if [ -d /var/lib/cyrus ] || [ -d /var/spool/cyrus ] || [ -d /var/spool/sieve ]; then
log_debug
echo "Enabling Cyrus spool purge."
echo "cyrus-common cyrus-common/removespools boolean true" | debconf-set-selections
fi
exit 0
piuparts-0.64ubuntu1/custom-scripts/scripts-no-usr-share-doc/ 0000775 0000000 0000000 00000000000 12517712417 021307 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-no-usr-share-doc/post_setup_disable_usr_share_doc 0000775 0000000 0000000 00000002563 12517712417 030033 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# skip while creating the tarball
exit 0
;;
esac
# clear out /usr/share/doc
# but keep the directories (and symlinks) as well as the copyright files
cat << EOF > /etc/dpkg/dpkg.cfg.d/piuparts-path-exclude
path-exclude=/usr/share/doc/*/*
path-include=/usr/share/doc/*/copyright
EOF
# switching init systems forth and back will clean out /usr/share/doc
# reinstalling the affected packages beforehand makes the files disappear
# before the snapshot of the reference system is created
CANDIDATES="systemd systemd-sysv sysv-rc"
CANDIDATES=$(dpkg-query -W $CANDIDATES | awk '{ if ($2) { print $1 } }')
if [ -n "$CANDIDATES" ]; then
echo "Reinstalling $(echo $CANDIDATES)..."
# workaround apt bug #770291 - do it one by one, not all at once
for package in $CANDIDATES
do
apt-get -u --reinstall install $package
done
fi
case ${PIUPARTS_OBJECTS%%=*} in
localepurge)
case ${PIUPARTS_DISTRIBUTION} in
lenny*|squeeze*) ;;
*)
# reinstall packages that will be reinstalled after purge
# to not record their /usr/share/doc content that is about to disappear
log_debug
EXTRA="base-passwd"
apt-get -u --reinstall --fix-missing install $(dpkg -S LC_MESSAGES | cut -d: -f1 | tr ', ' '\n' | sort -u) $EXTRA
;;
esac
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts-sysvinit/ 0000775 0000000 0000000 00000000000 12517712417 020111 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts-sysvinit/pre_distupgrade_zz_sysvinit 0000775 0000000 0000000 00000000177 12517712417 025720 0 ustar #!/bin/sh
set -e
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "jessie" ]; then
apt-get update
apt-get -y install sysvinit-core
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/ 0000775 0000000 0000000 00000000000 12517712417 016223 5 ustar piuparts-0.64ubuntu1/custom-scripts/scripts/post_setup_forbid_home 0000775 0000000 0000000 00000000552 12452567511 022716 0 ustar #!/bin/sh
set -e
case ${PIUPARTS_OBJECTS%%=*} in
dpkg)
# skip while creating the tarball
exit 0
;;
esac
case $PIUPARTS_DISTRIBUTION in
lenny|squeeze|squeeze-proposed)
exit 0
;;
esac
if [ -d /home ]; then
echo "Disabling /home"
mv /home /home.orig
echo "This is a dummy file to prevent creating directories in /home" > /home
chmod 000 /home
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_distupgrade_zz_upgrade_early 0000775 0000000 0000000 00000001571 12517712417 024764 0 ustar #!/bin/sh
set -e
# Skip while creating the reference chroot.
if [ "$PIUPARTS_PHASE" = "" ]; then
exit 0
fi
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
# packages to upgrade early
EARLY=
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "squeeze" ]; then
if dpkg-query -s "octave3.0" >/dev/null 2>&1
then
#696377
EARLY="$EARLY libblas3gf liblapack3gf"
fi
case ${PIUPARTS_OBJECTS%%=*} in
libapt-rpm-pkg-dev)
# libapt-rpm-pkg-dev no longer exists in squeeze
# causing some packages to be "kept back"
EARLY="$EARLY libreadline5-dev"
;;
python-pydoctor)
# work around #696376: "/usr/sbin/update-python-modules: /usr/bin/python: bad interpreter: No such file or directory"
EARLY="$EARLY python-pydoctor"
;;
esac
fi
if [ -n "$EARLY" ]; then
log_debug
echo "Upgrading early: $EARLY"
apt-get update
apt-get -y install $EARLY
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_squeeze-backports 0000775 0000000 0000000 00000000622 12452567511 025261 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_DISTRIBUTION" = "squeeze-backports" || exit 0
# apt-get -t squeeze-backports dist-upgrade may pull in too many
# packages that are not co-installable in squeeze-backports
# so maintain a list of packages in the sid base system
# that are in squeeze-backports, too, and don't cause problems
PKGS=""
PKGS="$PKGS insserv"
apt-get -y -t squeeze-backports install $PKGS
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_install_database-server 0000775 0000000 0000000 00000015251 12517712417 023621 0 ustar #!/bin/sh
set -e
# Install a database server for packages that require one during postinst
# but only recommend or suggest (or maybe not even this) the server
# package to allow for remote db servers.
MYSQL=
POSTGRESQL=
SQLITE3=
case ${PIUPARTS_OBJECTS%%=*} in
acidbase) MYSQL=yes ;;
auth2db) MYSQL=yes ;;
auth2db-common) MYSQL=yes ;;
auth2db-frontend) MYSQL=yes ;;
b2evolution) MYSQL=yes ;;
bacula-director-mysql) MYSQL=yes ;;
bacula-director-mysql-dbg) MYSQL=yes ;;
bacula-director-pgsql) POSTGRESQL=yes ;;
bacula-director-pgsql-dbg) POSTGRESQL=yes ;;
bandwidthd-pgsql) POSTGRESQL=yes ;;
bareos) POSTGRESQL=yes ;;
bareos-database-common) POSTGRESQL=yes ;;
bareos-database-mysql) POSTGRESQL=yes ; MYSQL=yes ;;
bareos-database-postgresql) POSTGRESQL=yes ;;
bareos-database-sqlite3) POSTGRESQL=yes ; SQLITE3=yes ;;
bareos-database-tools) POSTGRESQL=yes ;;
bareos-director) POSTGRESQL=yes ;;
bley) POSTGRESQL=yes ;;
blootbot) MYSQL=yes ;;
buddycloud-server) POSTGRESQL=yes ;;
bugzilla3) MYSQL=yes ;;
cacti) MYSQL=yes ;;
cacti-cactid) MYSQL=yes ;;
cacti-spine) MYSQL=yes ;;
chado-utils) POSTGRESQL=yes ;;
convirt) MYSQL=yes ;;
docbookwiki) MYSQL=yes ;;
dotclear) MYSQL=yes ;;
dotlrn) POSTGRESQL=yes ;;
drupal6) MYSQL=yes ;;
drupal6-mod-*) MYSQL=yes ;;
drupal6-thm-*) MYSQL=yes ;;
drupal6-trans-ru) MYSQL=yes ;;
drupal7) MYSQL=yes ;;
drupal7-mod-*) MYSQL=yes ;;
frontaccounting) MYSQL=yes ;;
fossology-agents) POSTGRESQL=yes ;;
fusionforge-plugin-blocks) POSTGRESQL=yes ;;
fusionforge-plugin-extsubproj) POSTGRESQL=yes ;;
fusionforge-plugin-gravatar) POSTGRESQL=yes ;;
fusionforge-plugin-hudson) POSTGRESQL=yes ;;
fusionforge-plugin-mediawiki) POSTGRESQL=yes ;;
fusionforge-plugin-moinmoin) POSTGRESQL=yes ;;
fusionforge-plugin-projectlabels) POSTGRESQL=yes ;;
fusionforge-plugin-scmarch) POSTGRESQL=yes ;;
fusionforge-plugin-scmcvs) POSTGRESQL=yes ;;
fusionforge-plugin-scmdarcs) POSTGRESQL=yes ;;
fusionforge-standard) POSTGRESQL=yes ;;
fusioninventory-for-glpi) MYSQL=yes ;;
gforge-lists-mailman) POSTGRESQL=yes ;;
gforge-plugin-extratabs) POSTGRESQL=yes ;;
gforge-plugin-mediawiki) POSTGRESQL=yes ;;
gforge-plugin-scmarch) POSTGRESQL=yes ;;
gforge-plugin-scmcvs) POSTGRESQL=yes ;;
gforge-plugin-scmdarcs) POSTGRESQL=yes ;;
gforge-plugin-scmgit) POSTGRESQL=yes ;;
gforge-plugin-scmhg) POSTGRESQL=yes ;;
gforge-web-apache2) POSTGRESQL=yes ;;
gforge-web-apache2-vhosts) POSTGRESQL=yes ;;
glance) SQLITE3=yes ;;
glance-api) SQLITE3=yes ;;
glance-common) SQLITE3=yes ;;
glance-registry) SQLITE3=yes ;;
glpi) MYSQL=yes ;;
gnuhealth-server) POSTGRESQL=yes ;;
grr) MYSQL=yes ;;
heat-api) SQLITE3=yes ;;
heat-api-cfn) SQLITE3=yes ;;
heat-api-cloudwatch) SQLITE3=yes ;;
heat-common) SQLITE3=yes ;;
heat-engine) SQLITE3=yes ;;
icinga-idoutils) POSTGRESQL=yes ;;
icinga-phpapi) MYSQL=yes ;;
icinga-web) POSTGRESQL=yes ;;
icinga-web-config-icinga) POSTGRESQL=yes ;;
icinga-web-config-icinga2-ido-mysql) MYSQL=yes ;;
icinga-web-config-icinga2-ido-pgsql) POSTGRESQL=yes ;;
icinga-web-pnp) POSTGRESQL=yes ;;
icinga2-ido-mysql) MYSQL=yes ;;
icinga2-ido-pgsql) POSTGRESQL=yes ;;
jclicmoodle) POSTGRESQL=yes ;;
jffnms) MYSQL=yes ;;
letodms) MYSQL=yes ;;
letodms-webdav) MYSQL=yes ;;
libchado-perl) POSTGRESQL=yes ;;
libdspam7-dbg) POSTGRESQL=yes ;;
libdspam7-drv-mysql) MYSQL=yes ;;
libdspam7-drv-pgsql) POSTGRESQL=yes ;;
mantis) MYSQL=yes ;;
moodle) POSTGRESQL=yes ; MYSQL=yes ;;
moodle-book) POSTGRESQL=yes ;;
moodle-debian-edu-*) POSTGRESQL=yes ;;
movabletype-opensource) SQLITE3=yes ;;
mtop) MYSQL=yes ;;
mythtv-database) MYSQL=yes ;;
nagvis) MYSQL=yes ;;
ndoutils-common) MYSQL=yes ;;
ndoutils-nagios3-mysql) MYSQL=yes ;;
neutron-common) SQLITE3=yes ;;
neutron-server) SQLITE3=yes ;;
neutron-*-agent) SQLITE3=yes ;;
nginx-naxsi-ui) MYSQL=yes ;;
ocsinventory-reports) MYSQL=yes ;;
ocsinventory-server) MYSQL=yes ;;
openacs) POSTGRESQL=yes ;;
openstack-dashboard) SQLITE3=yes ;;
openstack-dashboard-apache) SQLITE3=yes ;;
otrs) POSTGRESQL=yes ;;
otrs2) POSTGRESQL=yes
case "$PIUPARTS_DISTRIBUTION" in
lenny*|squeeze*) MYSQL=yes ;; #707075
esac ;;
pdns-backend-mysql) MYSQL=yes ;;
pdns-backend-pgsql) POSTGRESQL=yes ;;
phpbb3) MYSQL=yes ;;
phpbb3-l10n) MYSQL=yes ;;
phpgacl) MYSQL=yes ;;
phpmyadmin) MYSQL=yes ;;
phpwiki) MYSQL=yes ;;
pinba-engine-mysql-5.5) MYSQL=yes ;;
piwigo) MYSQL=yes ;;
pnopaste) MYSQL=yes ;;
poker-web) MYSQL=yes ;;
postfix-policyd) MYSQL=yes ;;
postfixadmin) MYSQL=yes ;;
prelude-manager) MYSQL=yes ;;
prewikka) MYSQL=yes ;;
pybit-web) POSTGRESQL=yes ;;
python-django-horizon) SQLITE3=yes ;;
python-quantum) SQLITE3=yes ;;
python-quantumclient) SQLITE3=yes ;;
quantum-common) SQLITE3=yes ;;
quantum-plugin-*) SQLITE3=yes ;;
quantum-server) SQLITE3=yes ;;
quantum-*-agent) SQLITE3=yes ;;
redmine) MYSQL=yes ;;
redmine-mysql) MYSQL=yes ;;
redmine-pgsql) POSTGRESQL=yes ;;
redmine-plugin-botsfilter) MYSQL=yes ;;
redmine-plugin-recaptcha) MYSQL=yes ;;
roundcube) MYSQL=yes ;;
roundcube-core) MYSQL=yes ;;
roundcube-plugins) MYSQL=yes ;;
roundcube-plugins-extra) MYSQL=yes ;;
rsyslog-mysql) MYSQL=yes ;;
rsyslog-pgsql) POSTGRESQL=yes ;;
scuttle) MYSQL=yes ;;
semanticscuttle) MYSQL=yes ;;
serendipity) MYSQL=yes ;;
simba) MYSQL=yes ;;
spotweb) MYSQL=yes ;;
sshproxy-backend-mysql) MYSQL=yes ;;
steam) MYSQL=yes ;;
sympa) MYSQL=yes ;;
tango-accesscontrol) MYSQL=yes ;;
tango-accesscontrol-dbg) MYSQL=yes ;;
tango-db) MYSQL=yes ;;
tango-db-dbg) MYSQL=yes ;;
textpattern) MYSQL=yes ;;
torrentflux) MYSQL=yes ;;
tt-rss) POSTGRESQL=yes ;;
tuskar) SQLITE3=yes ;;
tuskar-api) SQLITE3=yes ;;
tuskar-common) SQLITE3=yes ;;
tuskar-manager) SQLITE3=yes ;;
typo3-dummy) MYSQL=yes ;;
ukolovnik) MYSQL=yes ;;
webcalendar) MYSQL=yes ;;
webissues-server) MYSQL=yes ;;
websimba) MYSQL=yes ;;
wims-moodle) POSTGRESQL=yes ;;
zabbix-frontend-php) MYSQL=yes ;;
zabbix-proxy-mysql) MYSQL=yes ;;
zabbix-proxy-pgsql) POSTGRESQL=yes ;;
zabbix-server-mysql) MYSQL=yes ;;
zabbix-server-pgsql) POSTGRESQL=yes ;;
esac
if [ "$MYSQL" = "yes" ]; then
echo "Installing mysql-server..."
apt-get -y install mysql-server
fi
if [ "$POSTGRESQL" = "yes" ]; then
echo "Installing postgresql..."
apt-get -y install postgresql
fi
if [ "$SQLITE3" = "yes" ]; then
echo "Installing sqlite3..."
apt-get -y install sqlite3
fi
exit 0
piuparts-0.64ubuntu1/custom-scripts/scripts/post_purge_exceptions 0000775 0000000 0000000 00000001325 12452567511 022603 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
fai-nfsroot) log_debug
rm -f /.THIS_IS_THE_FAI_NFSROOT
;;
ltsp-client|\
ltsp-client-core) log_debug
rm -f /etc/ltsp_chroot
;;
amd64-libs|amd64-libs-dev)
# leaves a superfluous empty line after purge
log_debug
sed -i '3{/^$/d}' /etc/ld.so.conf
;;
localepurge)
case ${PIUPARTS_DISTRIBUTION} in
lenny*|squeeze*) ;;
*)
# reinstall packages where files might have been dropped
log_debug
EXTRA="base-passwd"
apt-get -u --reinstall --fix-missing install $(dpkg -S LC_MESSAGES | cut -d: -f1 | tr ', ' '\n' | sort -u) $EXTRA
;;
esac
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_40_find_missing_md5sums 0000775 0000000 0000000 00000002306 12452567511 025027 0 ustar #!/bin/sh
set -e
# skip the md5sum check if /usr/share/doc is pruned
test ! -f /etc/dpkg/dpkg.cfg.d/piuparts-path-exclude || exit 0
for pkg in ${PIUPARTS_OBJECTS%%=*}
do
# skip check if the package is not installed
dpkg-query -s "$pkg" >/dev/null 2>&1 || continue
status="$(dpkg-query -W -f '${Status}' $pkg)"
test "$status" != "unknown ok not-installed" || continue
test "$status" != "deinstall ok config-files" || continue
md5file="/var/lib/dpkg/info/$pkg.md5sums"
test -f "$md5file" || md5file="/var/lib/dpkg/info/$pkg:$(dpkg --print-architecture).md5sums"
if [ ! -f "$md5file" ]; then
echo "MD5SUM FILE NOT FOUND FOR $pkg"
continue
fi
f1=/var/run/f1.$$
sed -r 's%^[0-9a-f]{32} %/%' "$md5file" | sort >$f1
f2=/var/run/f2.$$
>$f2
dpkg -L "$pkg" | sort | \
while read f ; do
if [ -d "$f" ]; then
: # ignore directories
elif [ -L "$f" ]; then
: # ignore links
elif [ -z "${f%%/etc/*}" ]; then
: # ignore files in /etc - probably conffiles
elif [ ! -e "$f" ]; then
echo "${pkg}: MISSING OBJECT $f"
else
echo "$f" >> $f2
fi
done
comm -13 $f1 $f2 | sed "s/^/${pkg}: FILE WITHOUT MD5SUM /"
comm -23 $f1 $f2 | sed "s/^/${pkg}: MD5SUM WITHOUT FILE /"
rm -f $f1 $f2
done
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_exceptions 0000775 0000000 0000000 00000001571 12517712417 022561 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
isdnlog|isdnutils)
#WORKSAROUND #431855: fails with "There are still files in /etc/isdn/ that you may want to remove manually."
if [ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
log_debug
rm -fv /etc/isdn/*
fi
;;
apt-listbugs)
log_debug
# cleanup from post_install_exceptions
rm -f /usr/sbin/apt-listbugs
dpkg-divert --remove --rename /usr/sbin/apt-listbugs
;;
ffgtk|\
roger-router|\
roger-router-cli)
log_debug
# cleanup from pre_install_exceptions
dpkg-divert --remove --rename /usr/sbin/lpadmin
;;
esac
# Allow removal of the kernel running on the host from the chroot.
UNAME_R="$(uname -r)"
echo "linux-image-$UNAME_R linux-image-$UNAME_R/prerm/removing-running-kernel-$UNAME_R boolean false" | debconf-set-selections
piuparts-0.64ubuntu1/custom-scripts/scripts/post_setup_experimental 0000777 0000000 0000000 00000000000 12452567511 031204 2post_distupgrade_experimental ustar piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_exceptions 0000775 0000000 0000000 00000002242 12517712417 023772 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
if [ "$PIUPARTS_DISTRIBUTION" = "squeeze" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
linpopup)
# package removed after lenny
log_debug
for file in /var/lib/linpopup/messages.dat
do
test ! -f "$file" || chmod -c o-w "$file"
done
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "wheezy" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
kismet|\
tshark|\
wireshark|\
wireshark-common|\
wireshark-dbg|\
libcap2-bin)
# libcap2-bin/wheezy is part of the minimal chroot and recommends libpam-cap
# a conffile moved from libcap2-bin/squeeze to libpam-cap/wheezy
log_debug
apt-get install -yf libpam-cap
;;
phpgacl)
# #682825
# package not in wheezy
log_debug
for dir in /usr/share/phpgacl/admin/templates_c
do
test ! -d "$dir" || chmod -c o-w "$dir"
done
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "jessie" ]; then
# base-files only upgrades pristine /etc/nsswitch.conf
if grep -q ^gshadow: /etc/nsswitch.conf ; then
echo "Removing gshadow line from /etc/nsswitch.conf"
sed -i /^gshadow:/d /etc/nsswitch.conf
fi
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_setup_force-unsafe-io 0000775 0000000 0000000 00000000517 12452567511 023424 0 ustar #!/bin/sh
set -e
if [ ! -f /etc/dpkg/dpkg.cfg.d/piuparts-force-unsafe-io ]
then
if dpkg --force-help | grep -q unsafe-io
then
echo "Enabling dpkg --force-unsafe-io."
echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/piuparts-force-unsafe-io
fi
fi
if [ ! -h /bin/sync ]
then
dpkg-divert --rename /bin/sync
ln -sv true /bin/sync
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_setup_squeeze-backports 0000777 0000000 0000000 00000000000 12452567511 033130 2post_distupgrade_squeeze-backports ustar piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_base_cleanup 0000775 0000000 0000000 00000002574 12517712417 024242 0 ustar #!/bin/sh
set -e
#
# Remove obsolete base packages from the reference chroot.
#
# These packages are part of a minimal chroot in release R, but no
# longer exist in release R+1.
# Package dependencies will cause removal of the obsolete packages
# during a subset of upgrade paths. Since these packages cannot be
# reinstalled in release R+1 ensure they are always gone from the
# final reference chroot.
#
# Only while creating the reference chroot.
test "$PIUPARTS_PHASE" = "" || exit 0
PURGE=
mark_for_purge()
{
pkg="$1"
# skip if the package is not installed
dpkg-query -s "$pkg" >/dev/null 2>&1 || return 0
status="$(dpkg-query -W -f '${Status}' $pkg)"
test "$status" != "unknown ok not-installed" || return 0
test "$status" != "deinstall ok config-files" || return 0
case ${PIUPARTS_OBJECTS%%=*} in
$pkg)
# keep it while testing it
;;
*)
PURGE="$PURGE $pkg"
esac
}
if [ "$PIUPARTS_DISTRIBUTION" = "wheezy" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "wheezy-proposed" ] ; then
mark_for_purge libdb4.8
# gcc-4.4-base is part of the minimal squeeze chroot
# but it no longer exists in wheezy
mark_for_purge gcc-4.4-base
fi
if [ "$PIUPARTS_DISTRIBUTION" = "jessie" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "jessie-proposed" ] ; then
mark_for_purge libdb5.1
fi
if [ -n "$PURGE" ]; then
echo "Removing packages from base system:$PURGE"
apt-get -y remove --purge $PURGE
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_force-unsafe-io 0000777 0000000 0000000 00000000000 12452567511 031756 2post_setup_force-unsafe-io ustar piuparts-0.64ubuntu1/custom-scripts/scripts/pre_distupgrade_foreign_architecture_i386 0000775 0000000 0000000 00000001352 12517712417 026357 0 ustar #!/bin/sh
set -e
case "$PIUPARTS_DISTRIBUTION" in
squeeze*) ;;
*) exit 0 ;;
esac
case "$PIUPARTS_DISTRIBUTION_NEXT" in
lenny*|squeeze*) exit 0 ;;
esac
test "$(dpkg --print-architecture)" = "amd64" || exit 0
go=
case ${PIUPARTS_OBJECTS%%=*} in
ia32-libs|ia32-libs-gtk) go=yes ;;
lib32nss-mdns) go=yes ;;
*)
dpkg-query -s "ia32-libs" >/dev/null 2>&1 || exit 0
;;
esac
case ${PIUPARTS_OBJECTS} in
*=None) go=yes ;;
esac
case ${PIUPARTS_OBJECTS%%=*} in
*wine*) go=yes ;;
education-thin-client-server|education-workstation) go=yes ;;
playonlinux) go=yes ;;
esac
test -n "$go" || exit 0
echo "Enabling foreign architecture i386 for $PIUPARTS_OBJECTS"
apt-get update
apt-get -y install apt dpkg
dpkg --add-architecture i386
piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_hack_debsums 0000775 0000000 0000000 00000000457 12452567511 024250 0 ustar #!/bin/sh
set -e
# https://bugs.debian.org/687611
if [ -f /usr/share/keyrings/debian-archive-removed-keys.gpg~ ]; then
echo "FIXING /usr/share/keyrings/debian-archive-removed-keys.gpg~"
mv -v /usr/share/keyrings/debian-archive-removed-keys.gpg~ /usr/share/keyrings/debian-archive-removed-keys.gpg
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_install_foreign_architecture 0000775 0000000 0000000 00000001576 12517712417 024751 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_PHASE" = "install" || exit 0
case "$PIUPARTS_DISTRIBUTION" in
lenny*|squeeze*|wheezy*) exit 0 ;;
esac
FOREIGN=
case ${PIUPARTS_OBJECTS%%=*} in
crossbuild-essential-arm64|\
*-aarch64-linux-gnu)
FOREIGN="arm64"
;;
crossbuild-essential-armel|\
*-arm-linux-gnueabi)
FOREIGN="armel"
;;
crossbuild-essential-armhf|\
*-arm-linux-gnueabihf)
FOREIGN="armhf"
;;
*-mips-linux-gnu)
FOREIGN="mips"
;;
crossbuild-essential-mipsel|\
*-mipsel-linux-gnu)
FOREIGN="mipsel"
;;
crossbuild-essential-powerpc|\
*-powerpc-linux-gnu)
FOREIGN="powerpc"
;;
crossbuild-essential-ppc64el|\
*-powerpc64le-linux-gnu)
FOREIGN="ppc64el"
;;
esac
if [ -n "$FOREIGN" ] && [ "$FOREIGN" != "$(dpkg --print-architecture)" ]; then
echo "Enabling foreign architecture $FOREIGN for $PIUPARTS_OBJECTS"
dpkg --add-architecture $FOREIGN
apt-get update
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_distupgrade_exceptions 0000775 0000000 0000000 00000003433 12517712417 023576 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "squeeze" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
crm114)
#562946
log_debug
echo "crm114 crm114/forceupgrade boolean true" | debconf-set-selections
;;
esac
# squeeze does not properly upgrade adduser.conf, so generate a new one
if [ -f /etc/adduser.conf ]; then
md5="$(md5sum /etc/adduser.conf | awk '{ print $1 }')"
# 5b577c9cb18e4852fc7e45830d230ec1: adduser/lenny pristine
# 28928669e36f1ab616dfda39af3d79a7: adduser/lenny + dpsyco-lib/lenny
if [ "$md5" = "5b577c9cb18e4852fc7e45830d230ec1" ] || \
[ "$md5" = "28928669e36f1ab616dfda39af3d79a7" ]
then
rm -fv /etc/adduser.conf
fi
fi
fi
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "wheezy" ]; then
# dpkg 1.16 does not like the bad cnews version number cr.g7-40.4
# cnews was removed after lenny
case ${PIUPARTS_OBJECTS%%=*} in
cnews)
log_debug
dpkg --purge cnews
;;
esac
# WORKSAROUND #655969: lirc: prompting due to modified conffiles which where not modified by the user: /etc/lirc/hardware.conf
if [ -f /etc/lirc/hardware.conf ]; then
log_debug
sed -i '/^DRIVER=/s/.*/DRIVER="UNCONFIGURED"/' /etc/lirc/hardware.conf
fi
fi
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "jessie" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
ekeyd-uds)
# ekeyd-uds was removed after squeeze, maintainer scripts are incompatible with udev/jessie
log_debug
dpkg --purge ekeyd-uds
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION_NEXT" = "experimental" ]; then
case ${PIUPARTS_OBJECTS} in
dnscache-run=1:1.05-9~exp2)
#664848: breaks dns resolution in chroot if installed in a chroot
log_debug
echo "*** ABORT - Installation broke DNS in chroot ***"
exit 1
;;
esac
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_remove_exceptions 0000775 0000000 0000000 00000000543 12452567511 022757 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
file-rc)
case "$PIUPARTS_DISTRIBUTION" in
lenny|squeeze*)
log_debug
# removal wont work if sysv-rc isn't reinstalled
yes 'Yes, do as I say!' | apt-get -y --force-yes install sysv-rc
;;
esac
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_install_foreign_architecture_i386 0000775 0000000 0000000 00000000760 12452567511 025515 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_PHASE" = "install" || exit 0
case "$PIUPARTS_DISTRIBUTION" in
lenny*|squeeze*) exit 0 ;;
esac
test "$(dpkg --print-architecture)" = "amd64" || exit 0
case ${PIUPARTS_OBJECTS%%=*} in
ia32-libs|ia32-libs-gtk) ;;
libwine-unstable|libwine-*-unstable|wine|wine-unstable) ;;
boinc-nvidia-cuda|teamspeak-client) ;;
lib32nss-mdns) ;;
*) exit 0 ;;
esac
echo "Enabling foreign architecture i386 for $PIUPARTS_OBJECTS"
dpkg --add-architecture i386
apt-get update
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_test_root_password 0000775 0000000 0000000 00000000341 12452567511 022762 0 ustar #!/bin/sh
set -e
# sudo refuses removal if no root password is set, so set one
# do this unconditionally, as there are quite some packages depending on sudo
# (and since its harmless and fast)
yes "yes" 2>/dev/null | passwd
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_install_exceptions 0000775 0000000 0000000 00000013700 12517712417 022727 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
file-rc)
case "$PIUPARTS_DISTRIBUTION" in
lenny|squeeze*)
# force installation and removal of essential package sysv-rc
log_debug
yes 'Yes, do as I say!' | apt-get -y --force-yes install file-rc
;;
esac
;;
live-config-upstart|\
netscript-2.4-upstart|\
upstart)
case "$PIUPARTS_DISTRIBUTION" in
squeeze*|wheezy*)
# force installation and removal of essential package sysvinit
log_debug
yes 'Yes, do as I say!' | apt-get -y --force-yes install upstart
;;
esac
;;
upstart-dconf-bridge|\
upstart-monitor)
# switch init to upstart before installation
apt-get install upstart
;;
systemd-sysv)
case "$PIUPARTS_DISTRIBUTION" in
wheezy*)
# force installation and removal of essential package sysvinit
log_debug
yes 'Yes, do as I say!' | apt-get -y --force-yes install systemd-sysv
;;
esac
;;
esac
#
# the remaining exceptions are only for the initial package installation
#
if [ "$PIUPARTS_PHASE" != "install" ]; then
exit 0
fi
case ${PIUPARTS_OBJECTS%%=*} in
samhain) log_debug
# work around #749602
mkdir -p /var/state/samhain/
touch /var/state/samhain/samhain_file
;;
fai-nfsroot) log_debug
# fai-nfsroot refuses installation unless this file exist
touch /.THIS_IS_THE_FAI_NFSROOT
;;
education-thin-client|\
ltsp-client|\
ltsp-client-core) log_debug
# ltsp-client-core refuses installation unless this file exist
touch /etc/ltsp_chroot
;;
ffgtk|\
roger-router|\
roger-router-cli)
log_debug
# postinst tries to add a printer with lpadmin
dpkg-divert --rename /usr/sbin/lpadmin
;;
bugzilla3)
# checksetup.pl goes into infinite loop asking for them
log_debug
echo "bugzilla3 bugzilla3/bugzilla_admin_name string bz@local.host" | debconf-set-selections
echo "bugzilla3 bugzilla3/bugzilla_admin_real_name string Bz" | debconf-set-selections
echo "bugzilla3 bugzilla3/bugzilla_admin_pwd password bzbzbzbz" | debconf-set-selections
;;
esac
if [ "$PIUPARTS_DISTRIBUTION" = "wheezy-backports" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
libreoffice-style-*)
log_debug
apt-get -y -t $PIUPARTS_DISTRIBUTION install ${PIUPARTS_OBJECTS%%=*} libreoffice-common-
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "squeeze-backports" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
ekeyd)
log_debug
apt-get -y install udev
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "squeeze" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze-proposed" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze-backports" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
autopkgtest-xenlvm|\
clvm|\
cman|\
collectd|\
collectd-dbg|\
collectd-utils|\
dtc-xen|\
ganeti|\
ganeti2|\
gfs-tools|\
gfs2-tools|\
libcollectdclient0|\
libcollectdclient-dev|\
liblinux-lvm-perl|\
libsys-virt-perl|\
libvirt0|\
libvirt0-dbg|\
libvirt-dev|\
libvirt-ocaml|\
libvirt-ocaml-dev|\
libvirt-ruby|\
libvirt-ruby1.8|\
mozilla-virt-viewer|\
munin-libvirt-plugins|\
mylvmbackup|\
python-libvirt|\
redhat-cluster-suite|\
rgmanager|\
virtinst|\
virt-top|\
virt-viewer|\
xenwatch|\
lvm2)
# work around lvm2 bug https://bugs.debian.org/603036 which is squeeze-ignore
log_debug
apt-get -y install udev
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "squeeze" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
bootcd-ia64)
if [ "$PIUPARTS_TEST" = "distupgrade" ] && [ "$(uname -m)" = "x86_64" ]; then
#622690: bootcd-ia64 has a Pre-Depends/Depends cycle that apt cannot resolve
log_debug
apt-get -y install bootcd-i386
fi
;;
mini-buildd-bld|mini-buildd-rep)
#632955, #656746 - time limit exceeded during install
log_debug
echo "*** ABORT - Installation would deadlock ***"
exit 1
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
# install undeclared dependencies
case ${PIUPARTS_OBJECTS%%=*} in
clamav-getfiles)
#603082
log_debug
apt-get -y install curl
;;
cyrus-*-2.2|sa-learn-cyrus)
#694254 db4.2-util exists in lenny only and is needed for upgrades to wheezy
log_debug
apt-get -y install db4.2-util
;;
debian-edu-artwork-usplash)
# postinst fails without update-initramfs
log_debug
apt-get -y install initramfs-tools
;;
gforge-shell-postgresql|gforge-plugin-scmcvs|gforge-plugin-scmsvn)
#604218
log_debug
apt-get -y install libcap2
;;
otrs2)
#561889
log_debug
apt-get -y install libapache2-mod-perl2
;;
sdic-gene95)
#478592
log_debug
apt-get -y install bzip2 wget
;;
tftpd-hpa)
#522780
log_debug
apt-get -y install update-inetd
;;
ttf-beteckna)
#502707
log_debug
apt-get -y install defoma
;;
esac
# prefer inn over cnews (bad version number cr.g7-40.4)
case ${PIUPARTS_OBJECTS%%=*} in
newsx|post-faq)
log_debug
apt-get -y install inn
;;
esac
# work around postinst failures
case ${PIUPARTS_OBJECTS%%=*} in
ion3)
# annoying debconf prompt
log_debug
echo "ion3 ion3/acknowledge-maybe-outdated boolean true" | debconf-set-selections
echo "ion3 ion3/acknowledge-outdated boolean true" | debconf-set-selections
;;
ipppd|ibod|isdnutils)
#542156
log_debug
test -e /dev/MAKEDEV || ln -sfv /sbin/MAKEDEV /dev/MAKEDEV
;;
esac
# allow lenny kernel image installation in chroot
for flavor in amd64 openvz-amd64 vserver-amd64 xen-amd64 486 686 686-bigmem openvz-686 vserver-686 vserver-686-bigmem xen-686
do
echo "linux-image-2.6.26-2-$flavor linux-image-2.6.26-2-$flavor/preinst/bootloader-initrd-2.6.26-2-$flavor boolean false"
echo "linux-image-2.6.26-2-$flavor linux-image-2.6.26-2-$flavor/preinst/lilo-initrd-2.6.26-2-$flavor boolean false"
done | debconf-set-selections
# deterministic /bin/sh on upgrades
echo "dash dash/sh boolean true" | debconf-set-selections
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/post_distupgrade_experimental 0000775 0000000 0000000 00000001202 12452567511 024302 0 ustar #!/bin/sh
set -e
test "$PIUPARTS_DISTRIBUTION" = "experimental" || exit 0
# apt-get -t experimental dist-upgrade may pull in too many
# packages that are not co-installable in experimental
# so maintain a list of packages in the sid base system
# that are in experimental, too, and don't cause problems
PKGS=""
PKGS="$PKGS apt"
PKGS="$PKGS libc6"
PKGS="$PKGS libc-bin"
PKGS="$PKGS libgcc1"
PKGS="$PKGS libstdc++6"
PKGS="$PKGS multiarch-support"
PKGS="$PKGS findutils"
PKGS="$PKGS insserv"
PKGS="$PKGS dash"
PKGS="$PKGS libdbus-1-3"
PKGS="$PKGS grep"
PKGS="$PKGS libsystemd0"
PKGS="$PKGS libudev1"
apt-get -y -t experimental install $PKGS
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_40_find_obsolete_conffiles 0000775 0000000 0000000 00000001114 12452567511 025541 0 ustar #!/bin/sh
set -e
for pkg in ${PIUPARTS_OBJECTS%%=*}
do
dpkg-query -W -f='${Conffiles}\n' $pkg | \
grep ' obsolete$' | \
while read file md5expected obs
do
info="OBSOLETE CONFFILE $file REGISTERED BY $pkg"
query=$(dpkg-query -S $file)
owner=${query%: ${file}}
if [ "$owner" != "$pkg" ]; then
info="${info} OWNER CHANGED TO $owner"
fi
if [ ! -f "$file" ]; then
info="${info} (MISSING)"
else
md5=$(md5sum "$file" | awk '{ print $1 }')
if [ "$md5expected" != "$md5" ]; then
info="${info} (MODIFIED)"
fi
fi
echo "$info"
done
done
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_install_extras 0000775 0000000 0000000 00000001150 12452567511 022051 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts extra for package $PIUPARTS_OBJECTS"
}
if [ "$PIUPARTS_PHASE" = "install" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
*dkms)
log_debug
# Install kernel headers, so that dkms tries to build a module
HEADERS=linux-headers
FLAVOR=unknown
FLAVOR_i386=686-pae
case $PIUPARTS_DISTRIBUTION in
lenny*|squeeze*)
HEADERS=linux-headers-2.6
FLAVOR_i386=686
;;
esac
case $(dpkg --print-architecture) in
amd64)
FLAVOR=amd64
;;
i386)
FLAVOR=$FLAVOR_i386
;;
esac
apt-get -y install $HEADERS-$FLAVOR
;;
esac
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_40_find_unowned_lib_links 0000775 0000000 0000000 00000000716 12517712417 025410 0 ustar #!/bin/sh
set -e
for libdir in /lib /usr/lib /lib/*-gnu* /usr/lib/*-gnu*
do
test -d "$libdir" || continue
for f in "$libdir"/*
do
test ! -d "$f" || continue
test -L "$f" || continue
rl=$(readlink "$f")
test -n "${rl##/etc/alternatives/*}" || continue
if ! dpkg-query -S "$f" >/dev/null 2>&1
then
case "$f" in
/lib/ld-lsb.so.?)
# created by lsb-core
;;
*)
echo "UNOWNED SYMLINK $f -> $rl"
;;
esac
fi
done
done
piuparts-0.64ubuntu1/custom-scripts/scripts/post_install_exceptions 0000775 0000000 0000000 00000000723 12452567511 023130 0 ustar #!/bin/sh
set -e
log_debug() {
echo "Debug: piuparts exception for package $PIUPARTS_OBJECTS"
}
case ${PIUPARTS_OBJECTS%%=*} in
apt-listbugs) log_debug
# when installed apt-listbugs is run on installations / upgrades
# and will cause them to fail due to prompting
# if packages being installed currently have RC bugs.
# so disable it here.
dpkg-divert --rename /usr/sbin/apt-listbugs
ln -svf /bin/true /usr/sbin/apt-listbugs
;;
esac
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_distupgrade_zz_database-server 0000775 0000000 0000000 00000001656 12517712417 025215 0 ustar #!/bin/sh
set -e
# Skip while creating the reference chroot.
if [ "$PIUPARTS_PHASE" = "" ]; then
exit 0
fi
CANDIDATES=""
CANDIDATES="$CANDIDATES mysql-server"
CANDIDATES="$CANDIDATES mysql-server-5.5"
CANDIDATES="$CANDIDATES postgresql"
CANDIDATES="$CANDIDATES postgresql-8.4"
CANDIDATES="$CANDIDATES postgresql-9.1"
PACKAGES=""
# early upgrade runs into even more trouble for some packages ...
case ${PIUPARTS_OBJECTS%%=*} in
med-practice|audiolink)
CANDIDATES=""
;;
redmine)
CANDIDATES=""
;;
esac
for pkg in $CANDIDATES
do
# skip if the package is not installed
dpkg-query -s "$pkg" >/dev/null 2>&1 || continue
status="$(dpkg-query -W -f '${Status}' $pkg)"
test "$status" != "unknown ok not-installed" || continue
test "$status" != "deinstall ok config-files" || continue
PACKAGES="$PACKAGES $pkg"
done
if [ -n "$PACKAGES" ]
then
echo "Upgrading ${PACKAGES# } early"
apt-get update
apt-get -y install $PACKAGES
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_50_find_bad_permissions 0000775 0000000 0000000 00000004420 12517712417 025061 0 ustar #!/bin/sh
set -e
case "$PIUPARTS_DISTRIBUTION" in
lenny)
case ${PIUPARTS_OBJECTS%%=*} in
linpopup)
# package removed after lenny
for file in /var/lib/linpopup/messages.dat
do
test ! -f "$file" || chmod -c o-w "$file"
done
;;
esac
;;
esac
if [ "$PIUPARTS_DISTRIBUTION" = "squeeze" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze/updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze-updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze-proposed-updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "squeeze-proposed" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "lenny" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
citadel-server|citadel-dbg|citadel-mta|citadel-suite|bcron-run|capisuite|debbugs|raccess4vbox3|smartlist|sxid)
#WORKSAROUND #684964: citadel-server: world writable config file: /etc/citadel/netconfigs/7
for file in /etc/citadel/netconfigs/7 /etc/citadel/refcount_adjustments.dat /etc/citadel/citadel.control
do
test ! -f "$file" || chmod -c o-w "$file"
done
;;
esac
fi
if [ "$PIUPARTS_DISTRIBUTION" = "wheezy" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "wheezy/updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "wheezy-updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "wheezy-proposed-updates" ] || \
[ "$PIUPARTS_DISTRIBUTION" = "wheezy-proposed" ]; then
case ${PIUPARTS_OBJECTS%%=*} in
citadel-server|citadel-dbg|citadel-mta|citadel-suite|bcron|bcron-run|capisuite|debbugs|exmh|nmh|raccess4vbox3|smartlist|xlbiff)
#WORKSAROUND #684964: citadel-server: world writable config file: /etc/citadel/netconfigs/7
for file in /etc/citadel/netconfigs/7 /etc/citadel/refcount_adjustments.dat /var/lib/citadel/data/refcount_adjustments.dat
do
test ! -f "$file" || chmod -c o-w "$file"
done
;;
esac
fi
case ${PIUPARTS_OBJECTS%%=*} in
gpe-tetris|gpe)
#WORKSAROUND #684178: gpe-tetris: creates world writable directory /var/games/gpe
# package removed after wheezy
for file in /var/games/gpe/gpe-tetris.dat
do
test ! -f "$file" || chmod -c o-w "$file"
done
for dir in /var/games/gpe
do
test ! -d "$dir" || chmod -c o-w "$dir"
done
;;
esac
# find world writables without sticky bit
BADPERMS=$(find / -mount ! -type l ! -type c ! -type p ! -type s -perm -o+w ! -perm -1000)
if [ -n "$BADPERMS" ]; then
echo "ERROR: BAD PERMISSIONS"
ls -lad $BADPERMS
exit 1
fi
piuparts-0.64ubuntu1/custom-scripts/scripts/pre_remove_50_find_missing_copyright 0000775 0000000 0000000 00000002370 12452567511 025444 0 ustar #!/bin/sh
set -e
failed=
for pkg in ${PIUPARTS_OBJECTS%%=*}
do
# ignore failures for some old packages with many rdepends
ignore=
case "${pkg}_${PIUPARTS_DISTRIBUTION}" in
gij_lenny) ignore=1 ;;
gnumeric-common_lenny) ignore=1 ;; #554201
libuim6_lenny) ignore=1 ;; #554204
libuim-data_lenny) ignore=1 ;; #554200
mozilla-plugin-vlc_lenny) ignore=1 ;; #687657
postgresql-8.3-plsh_lenny) ignore=1 ;; # removed after lenny
vlc_lenny) ignore=1 ;; #687657
cdd-common_squeeze) ignore=1 ;; #692946
libfbclient2_squeeze) ignore=1 ;; #692948
libcucul0_wheezy) ignore=1 ;; # removed
esac
# skip check if the package is not installed
dpkg-query -s "$pkg" >/dev/null 2>&1 || continue
status="$(dpkg-query -W -f '${Status}' $pkg)"
test "$status" != "unknown ok not-installed" || continue
test "$status" != "deinstall ok config-files" || continue
docdir="/usr/share/doc/$pkg"
copyright="$docdir/copyright"
if [ ! -f "$copyright" ]
then
if [ -n "$ignore" ]; then
echo "ignoring failure of $pkg on $PIUPARTS_DISTRIBUTION"
else
failed="$failed $copyright"
fi
echo "MISSING COPYRIGHT FILE: $copyright"
echo "# ls -lad $docdir"
ls -lad "$docdir" || true
echo "# ls -la $docdir/"
ls -la "$docdir/" || true
fi
done
piuparts-0.64ubuntu1/slave-bin/ 0000775 0000000 0000000 00000000000 12536542664 013423 5 ustar piuparts-0.64ubuntu1/slave-bin/slave_run.in 0000775 0000000 0000000 00000004405 12452567512 015753 0 ustar #!/bin/sh
set -e
# Copyright 2009-2013 Holger Levsen (holger@layer-acht.org)
# Copyright © 2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Run (several) piuparts-slave instance(s) in screen to allow interactive
# control later on.
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value PYTHONPATH global PYTHONPATH ''
get_config_value SLAVEROOT global slave-directory
get_config_value PIUPARTS_TMPDIR global tmpdir
get_config_value SLAVECOUNT global slave-count 1
export PYTHONPATH
SESSIONNAME=piuparts_slave_screen
SCREENLOG=$SLAVEROOT/screenlog.0
if ! screen -ls $SESSIONNAME | grep -q "No Sockets found" ; then
echo "piuparts-slave is already running!"
echo
screen -ls
exit 1
fi
# cleanup cruft from previous runs
@sharedir@/piuparts/slave/slave_cleanup
rm -f $SCREENLOG
# ensure the temporary directory exists
mkdir -p $PIUPARTS_TMPDIR
mkdir -p $SLAVEROOT
cd $SLAVEROOT
# Ensure the screen session exists, run normal shell in screen 0
screen -S $SESSIONNAME -d -m
echo "Started screen session '$SESSIONNAME'."
# run this on a single slave or a sequence of slaves
# FIXME: this should really test whether $1 is an integer and within SLAVECOUNT
if [ "$1" != "" ] ; then
SLAVES=$1
else
SLAVES="$(seq $SLAVECOUNT)"
fi
for SLAVENUM in $SLAVES
do
mkdir -p $SLAVENUM
SLAVEDIR=$(readlink -f $SLAVENUM)
# Ensure there is a window for this slave.
screen -S $SESSIONNAME -X screen -t slave$SLAVENUM -L $SLAVENUM
# Launch the slave.
screen -S $SESSIONNAME -p $SLAVENUM -X stuff "
cd $SLAVEDIR
@sharedir@/piuparts/piuparts-slave
"
echo "piuparts-slave $SLAVENUM has been started."
done
piuparts-0.64ubuntu1/slave-bin/detect_slave_problems.in 0000775 0000000 0000000 00000004217 12452567512 020323 0 ustar #!/bin/sh
set -e
# Copyright 2009-2010 Holger Levsen (holger@layer-acht.org)
# Copyright © 2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# this scripts monitors the output of piuparts-slave
# when running in screen started by ~piupartss/bin/slave_run
#
. @sharedir@/piuparts/lib/read_config.sh
# outputs file age in seconds (or 0 if the file does not exist)
file_age()
{
if [ -e "$1" ]; then
local ctime now
ctime=$(stat -c %Z "$1" 2>/dev/null || echo 0)
now=$(date +%s)
echo $(($now - $ctime))
else
echo "0"
fi
}
get_config_value SLAVEROOT global slave-directory
get_config_value IDLE_SLEEP global idle-sleep 1800
SCREENLOG=$SLAVEROOT/screenlog.0
STATEFILE=$SLAVEROOT/slave-problems
# clear the statefile daily and whine again
test $(file_age $STATEFILE) -lt 86000 || rm -f $STATEFILE
# Only complain if screenlog is older than $IDLE_SPEEP + 1 minute (the slave
# likes to sleep that long) and the problem is new or was not reported within
# the previous 24 hours.
if [ $(file_age $SCREENLOG) -le $(($IDLE_SLEEP + 60)) ]; then
rm -f $STATEFILE
elif [ ! -f $STATEFILE ]; then
{
echo "Either a test is running for a very long time (but no test"
echo "should run longer than an hour), piuparts-slave hangs or is"
echo "not running at all or wasn't started with"
echo "~piupartss/bin/slave_run - please investigate and take"
echo "appropriate measures!"
echo
tail $SCREENLOG
} | mail -s "problem with piuparts-slave detected" piupartss
touch $STATEFILE
fi
piuparts-0.64ubuntu1/slave-bin/detect_leftover_processes.in 0000775 0000000 0000000 00000003742 12452567512 021224 0 ustar #!/bin/sh
set -e
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2012-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# find processes running in deleted chroots
#
. @sharedir@/piuparts/lib/read_config.sh
# outputs file age in seconds (or 0 if the file does not exist)
file_age()
{
if [ -e "$1" ]; then
local ctime now
ctime=$(stat -c %Z "$1" 2>/dev/null || echo 0)
now=$(date +%s)
echo $(($now - $ctime))
else
echo "0"
fi
}
get_config_value SLAVEROOT global slave-directory
get_config_value PIUPARTS_TMPDIR global tmpdir
STATEFILE=$SLAVEROOT/leftover_processes
# clear the statefile daily and whine again
test $(file_age $STATEFILE) -lt 86000 || rm -f $STATEFILE
OUTPUT="$(sudo ls --color=never -lad /proc/*/root 2>/dev/null | grep "$PIUPARTS_TMPDIR" | grep "(deleted)")"
if [ -z "$OUTPUT" ]; then
rm -f $STATEFILE
elif [ "$(cat $STATEFILE 2>/dev/null)" != "$OUTPUT" ]; then
echo "Found processes running with a deleted chroot in $PIUPARTS_TMPDIR"
echo "This is usually because of 'FAIL: Processes are running inside chroot' which"
echo "usually means the package violates 'must use invoke-rc.d (policy 9.3.3.2)'."
echo
echo "$OUTPUT"
echo
echo "Please cleanup manually."
echo "Since #522918 has been fixed this should no longer happen."
echo "$OUTPUT" > $STATEFILE
fi
piuparts-0.64ubuntu1/slave-bin/detect_tmp_cruft.in 0000775 0000000 0000000 00000003267 12452567512 017315 0 ustar #!/bin/sh
set -e
# Copyright 2009 Holger Levsen (holger@layer-acht.org)
# Copyright © 2012-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# check for stale mounts and chroots in $PIUPARTS_TMPDIR
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value PIUPARTS_TMPDIR global tmpdir
MOUNTS="$(mktemp)"
cp /proc/mounts "$MOUNTS"
if [ "$(grep -v trash "$MOUNTS" | grep -c "$PIUPARTS_TMPDIR")" -gt 1 ] ; then
echo "More than one mountpoint below $PIUPARTS_TMPDIR detected!"
echo
grep "$PIUPARTS_TMPDIR" "$MOUNTS"
echo
echo "Zero or one mountpoint is normal for piuparts operation, more is not."
echo "Please investigate and cleanup."
echo
fi
rm "$MOUNTS"
LS_TMP=$(ls --color=never -l "$PIUPARTS_TMPDIR")
if [ "$(echo "$LS_TMP" | wc -l)" -gt 12 ] ; then
echo "More than ten directories in $PIUPARTS_TMPDIR detected!"
echo
echo "$LS_TMP"
echo
echo "$(du -shx "$PIUPARTS_TMPDIR" 2>/dev/null)"
echo
echo "One is normal for piuparts operation, more is not."
echo "Please investigate and cleanup."
echo
fi
piuparts-0.64ubuntu1/slave-bin/slave_join 0000775 0000000 0000000 00000002407 12452567512 015501 0 ustar #!/bin/sh
set -e
# Copyright 2009-2010 Holger Levsen (holger@layer-acht.org)
# Copyright © 2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# reattach to an existing slave session
#
SESSIONNAME=piuparts_slave_screen
if screen -ls $SESSIONNAME | grep -q "No Sockets found" ; then
echo "piuparts-slave not running!"
echo
echo "ps faxu | grep piuparts"
ps faxu | grep piuparts
echo
echo "screen -ls"
screen -ls
exit 1
fi
if [ -w $(tty) ]; then
screen -x -S $SESSIONNAME
else
# use script hack to get a new writable tty
script -q -c "screen -x -S $SESSIONNAME" /dev/null
fi
piuparts-0.64ubuntu1/slave-bin/slave_cleanup.in 0000775 0000000 0000000 00000003132 12452567512 016572 0 ustar #!/bin/sh
set -e
# Copyright 2012 Holger Levsen (holger@layer-acht.org)
# Copyright © 2012-2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# cleanup old chroots etc. in $PIUPARTS_TMPDIR
#
# - this should only be run (automatically) on boot
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value PIUPARTS_TMPDIR global tmpdir
# do nothing if piuparts-slave is running
if pgrep -f share/piuparts/piuparts-slave >/dev/null ; then
exit 0
fi
# umount all mount points (should be none on boot, but this script can also be called at other times)
for MOUNTPOINT in $(tac /proc/mounts | cut -d " " -f 2 | grep "$PIUPARTS_TMPDIR/")
do
sudo umount "$MOUNTPOINT"
done
# cleanup tmp
mkdir -p "$PIUPARTS_TMPDIR"
for dir in $(ls -d1 "$PIUPARTS_TMPDIR"/*/ 2>/dev/null || true)
do
if sudo test -f "$dir/.piuparts.tmpdir"; then
sudo rm -rf --one-file-system "$dir"
test ! -d "$dir" || sudo touch "$dir/.piuparts.tmpdir"
fi
done
piuparts-0.64ubuntu1/piuparts_slave_run.8.txt 0000664 0000000 0000000 00000003136 12536542721 016374 0 ustar piuparts_slave_run(8)
=====================
:doctype: manpage
:revdate: 2013-05-27
NAME
----
piuparts_slave_run - start up piuparts-slave instance(s) in screen
SYNOPSIS
--------
*piuparts_slave_run* ['SLAVE-NUMBERS']
DESCRIPTION
-----------
*piuparts_slave_run* runs piuparts-slave instance(s) in *screen* which run *piuparts* tests which test whether Debian packages handle installation, upgrading, and removal correctly.
By default, *piuparts_slave_run* will start the number of slaves specified by the 'slave-count' parameter in the piuparts.conf file. If 'slave-count' is not defined, a single slave will be started. If a single argument is supplied to *piuparts_slave_run*, consisting of a space-separated list of numbers between 1 and 'slave-count', only those slaves will be started.
OPTIONS
-------
There are no options to this command currently. Note however that *this interface is under development* and may change.
ENVIRONMENT
-----------
Running piuparts in master-slave mode requires configuration in _/etc/piuparts_.
BUGS
----
*piuparts_slave_run* should be able to run slaves in different ways:
1. all, in a new screen (only this is implemented at the moment)
2. a specific one, in a specified screen slot in a (running) screen
3. append one to a (running) screen using a "random" slot
4. start slave in the current directory in the current shell in foreground.
NOTES
-----
Make sure to also read */usr/share/doc/piuparts-master/README_server.txt*.
SEE ALSO
--------
*piuparts*(1), *piuparts_slave_join*(8), *screen*(1)
AUTHOR
------
Holger Levsen (holger@layer-acht.org)
// vim: set filetype=asciidoc:
piuparts-0.64ubuntu1/README.txt 0000664 0000000 0000000 00000020543 12452567511 013240 0 ustar piuparts README
---------------
Author: Lars Wirzenius
Email:
After reading this README you probably also want to have a look
at the piuparts manpage, to learn about the available options.
But read this document first!
== Introduction
piuparts is a tool for testing that .deb packages can be
installed, upgraded, and removed without problems. The
name, a variant of something suggested by Tollef Fog
Heen, is short for "package installation, upgrading, and
removal testing suite".
piuparts is licensed under the GNU General Public License,
version 2, or (at your option) any later version.
https://piuparts.debian.org has been testing the Debian archive
since the Lenny release in 2009, though responsible maintainers
run piuparts locally before uploading packages to the archive.
== How to use piuparts in 5 minutes
=== Basic Usage
Testing your packages with piuparts is as easy as typing at the
console prompt:
----
# piuparts sm_0.6-1_i386.deb
----
Note that in order to work, piuparts has to be executed as user
root, so you need to be logged as root or use 'sudo'.
This will create a sid chroot with debootstrap, where it'll test
your package.
If you want to test your package in another release, for example,
testing, you can do so with:
----
# piuparts ./sm_0.6-1_i386.deb -d testing
----
By default, this will read the first mirror from your
'/etc/apt/sources.list' file. If you want to specify a different
mirror you can do it with the option '-m':
----
# piuparts ./sm_0.6-1_i386.deb -m http://ftp.de.debian.org/debian
----
It's possible to use -d more than once. For example, to do a first
installation in stable, then upgrade to testing, then upgrade to
unstable and then upgrade to the local package use this:
----
# piuparts -d stable -d testing -d unstable ./sm_0.6-1_i386.deb
----
=== Some tips
piuparts also has a manpage, where all available options are explained.
If you use piuparts on a regular basis, waiting for it to create
a chroot every time takes too much time, even if you are using a
local mirror or a caching tool such as approx.
Piuparts has the option of using a tarball as the contents of the
initial chroot, instead of building a new one with debootstrap. A
easy way to use this option is use a tarball created with
pbuilder. If you are not a pbuilder user, you can create this
tarball with the command (again, as root):
----
# pbuilder --create
----
then you only have to remember to update this tarball with:
----
# pbuilder --update
----
To run piuparts using this tarball:
----
# piuparts -p ./sm_0.6-1_i386.deb
----
If you want to use your own pre-made tarball:
----
# piuparts --basetgz=/path/to/my/tarball.tgz ./sm_0.6-1_i386.deb
----
Piuparts also has the option of using a tarball as the contents
of the initial chroot, instead of building a new one with
pbuilder. You can save a tarball for later use with the '-s'
('--save') piuparts option. Some people like this, others prefer
to only have to maintain one tarball. Read the piuparts manpage
about the '-p', '-b' and '-s' options
While pbuilder itself supports using cdebootstrap, this is not
fully supported by piuparts: You will need to use debootstrap
or use the '--warn-on-debsums-errors' option for piuparts and then
you will still see spurious warnings in the log.
=== Piuparts tests
By default, piuparts does two tests:
. Installation and purging test.
. Installation, upgrade and purging tests.
The first test installs the package in a minimal chroot, removes
it and purges it. The second test installs the current version in
the archive of the given packages, then upgrades to the new
version (deb files given to piuparts in the input), removes and
purges.
If you only want to perfom the first test, you can use the
option: '--no-upgrade-test'
=== Testing packages in the config-files-remaining state
The --install-remove-install option modifies the three piuparts
tests in order to test package installation while config files
from a previous installation are remaining, but the package itself
was removed inbetween.
This exercises different code paths in the maintainer scripts.
. Installation and purging test: install, remove, install again
and purge.
. Installation, upgrade and purging test: install the old version,
remove, install the new version and purge.
. Distupgrade test: install the version from the first
distribution, remove, distupgrade to the last distribution,
install the new version.
=== Analyzing piuparts results
When piuparts finishes all the tests satisfactorily, you will get
these lines as final output:
----
0m39.5s INFO: PASS: All tests.
0m39.5s INFO: piuparts run ends.
----
Anyway, it is a good idea to read the whole log in order to
discover possible problems that did not stop the piuparts
execution.
If you do not get those lines, piuparts has failed during a test.
The latest lines should give you a pointer to the problem with
your package.
== Custom scripts with piuparts
You can specify several custom scripts to be run inside piuparts.
You have to store them in a directory and give it as argument to
piuparts: '--scriptsdir=/dir/with/the/scripts'
This option can be given multiple times. The scripts from all
directories will be merged together (and later ones may overwrite
earlier scripts with the same filename).
By default this is *not* set to anything. Have a look at
'/etc/piuparts/scripts*' to learn which scripts and script
directories are shipped by the package.
The script prefix determines in which step it is executed. You
can run several scripts in every step, they are run in
alphabetical order.
The scripts need to be executable and are run *inside* the piuparts
chroot and can only be shell scripts. If you want to run Python or
Perl scripts, you have to install Python or Perl. The chroot where
piuparts is run is minimized and does not include Perl.
The variable PIUPARTS_OBJECTS is set to the packages currently
being tested (seperated by spaces, if applicable) or the .changes
file(s) being used. So when running in master-slave mode, it
will be set to the (one) package being tested at a time.
Depending on the current test, the variable PIUPARTS_TEST is set
to
. 'install' (installation and purging test),
. 'upgrade' (installation, upgrade and purging tests) or
. 'distupgrade'.
During the 'upgrade' and 'distupgrade' tests, the variable
PIUPARTS_PHASE is set to one of the following values:
. 'install' while initially installing the packages from the
repository,
. 'upgrade' when upgrading to the .debs,
. 'distupgrade' while reinstalling the packages after
'apt-get dist-upgrade' to ensure they were not removed accidently
During the 'install' test, the PIUPARTS_PHASE variable is set to
'install'.
The current distribution is available in the variable
PIUPARTS_DISTRIBUTION.
The following prefixes for scripts are recognized:
'post_chroot_unpack' - after the chroot has been unpacked/debootrapped.
Before the chroot gets updated/dist-upgraded initially.
'post_setup_' - after the *setup* of the chroot is finished.
Before metadata of the chroot is recorded for later comparison.
'pre_test_' - at the beginning of each test. After metadata of
the chroot was recorded for later comparison.
'pre_install_' - before *installing* your package. Depending on
the test, this may be run multiple times. The PIUPARTS_TEST and
PIUPARTS_PHASE variables can be used to distinguish the cases.
'post_install_' - after *installing* your package and its
dependencies. Depending on the test, this may be run multiple
times. The PIUPARTS_TEST and PIUPARTS_PHASE variables can be used
to distinguish the cases.
'pre_remove_' - before *removing* your package.
'post_remove_' - after *removing* your package.
'post_purge_' - after *purging* your package. Right before
comparing the chroot with the initially recorded metadata.
'pre_distupgrade_' - before *upgrading* the chroot to the *next
distribution*. The next distribution is available in the variable
PIUPARTS_DISTRIBUTION_NEXT.
'post_distupgrade_' - after *upgrading* the chroot to the *next
distribution*. The previous distribution is available in the
variable PIUPARTS_DISTRIBUTION_PREV.
=== Example custom scripts:
'$ cat post_install_numbers'
----
#!/bin/bash
number=`dpkg -l | wc -l`
echo "There are $number packages installed."
exit 0
----
'$ cat post_setup_package'
----
#!/bin/sh
echo "$PIUPARTS_OBJECTS will now get tested."
exit 0
----
== Distributed testing
This is described in README_server.txt.
// vim: set filetype=asciidoc:
piuparts-0.64ubuntu1/Makefile 0000664 0000000 0000000 00000013373 12517712417 013204 0 ustar prefix = /usr/local
sbindir = $(prefix)/sbin
sharedir = $(prefix)/share
mandir = $(sharedir)/man
man1dir = $(mandir)/man1
man8dir = $(mandir)/man8
libdir = $(prefix)/lib
docdir = $(prefix)/share/doc/piuparts/
site27 = $(libdir)/python2.7/dist-packages
htdocsdir = $(sharedir)/piuparts/htdocs
etcdir = $(prefix)/etc
distribution=${shell dpkg-parsechangelog | sed -n 's/^Distribution: *//p'}
ifeq ($(distribution),UNRELEASED)
version := ${shell echo "`dpkg-parsechangelog | sed -n 's/^Version: *//p'`~`date +%Y%m%d%H%M`~`git describe --dirty`"}
else
version := ${shell dpkg-parsechangelog | sed -n 's/^Version: *//p'}
endif
# generate several scripts, conffiles, ... from templates (*.in, *.py)
# by substituting placeholders
SCRIPTS_TEMPLATES = $(wildcard *.in master-bin/*.in slave-bin/*.in conf/*.in)
SCRIPTS_PYTHON_BINARY = $(wildcard *.py master-bin/*.py slave-bin/*.py)
SCRIPTS_GENERATED = $(SCRIPTS_TEMPLATES:.in=) $(SCRIPTS_PYTHON_BINARY:.py=)
DOCS_GENERATED = piuparts.1 piuparts.1.html piuparts_slave_run.8 piuparts_slave_join.8 README.html README_server.html
define placeholder_substitution
sed -r \
-e 's/__PIUPARTS_VERSION__/$(version)/g' \
-e 's%@sharedir@%$(sharedir)%g' \
$< > $@
endef
%: %.in Makefile
$(placeholder_substitution)
%: %.py Makefile
$(placeholder_substitution)
all: build
python_scripts = $(wildcard *.py piupartslib/*.py master-bin/*.py slave-bin/*.py)
python-syntax-check:
@set -e -x; $(foreach py,$(python_scripts),python -m py_compile $(py);)
$(RM) $(python_scripts:=c)
build: build-stamp
build-stamp: $(SCRIPTS_GENERATED) $(DOCS_GENERATED) Makefile
$(MAKE) python-syntax-check
touch $@
build-doc: $(DOCS_GENERATED)
README.html: README.txt
a2x --copy -a toc -a toclevels=3 -f xhtml -r /etc/asciidoc/ README.txt
README_server.html: README_server.txt
a2x --copy -a toc -a toclevels=3 -f xhtml -r /etc/asciidoc/ README_server.txt
piuparts.1: piuparts.1.txt
a2x -f manpage piuparts.1.txt
piuparts_slave_run.8: piuparts_slave_run.8.txt
a2x -f manpage piuparts_slave_run.8.txt
piuparts_slave_join.8: piuparts_slave_join.8.txt
a2x -f manpage piuparts_slave_join.8.txt
piuparts.1.html: piuparts.1.txt
a2x --copy -f xhtml piuparts.1.txt
install-doc: build-stamp
install -d $(DESTDIR)$(docdir)/
install -m 0644 README.txt README.html README_server.txt README_server.html docbook-xsl.css $(DESTDIR)$(docdir)/
install -d $(DESTDIR)$(man1dir)
install -m 0644 piuparts.1 $(DESTDIR)$(man1dir)/
install -d $(DESTDIR)$(man8dir)
install -m 0644 piuparts_slave_run.8 piuparts_slave_join.8 $(DESTDIR)$(man8dir)/
gzip -9f $(DESTDIR)$(man1dir)/piuparts.1
gzip -9f $(DESTDIR)$(man8dir)/piuparts_slave_run.8
gzip -9f $(DESTDIR)$(man8dir)/piuparts_slave_join.8
install -m 0644 piuparts.1.html $(DESTDIR)$(docdir)/
install-conf: build-stamp
install -d $(DESTDIR)$(etcdir)/piuparts
install -m 0644 conf/piuparts.conf.sample $(DESTDIR)$(etcdir)/piuparts/piuparts.conf
install -m 0644 conf/distros.conf $(DESTDIR)$(etcdir)/piuparts/
install -d $(DESTDIR)$(etcdir)/apache2/conf-available
install -m 0644 conf/piuparts-master.conf $(DESTDIR)$(etcdir)/apache2/conf-available/
install-conf-4-running-from-git: build-stamp
install -d $(DESTDIR)$(etcdir)/piuparts
install -m 0644 conf/crontab-master $(DESTDIR)$(etcdir)/piuparts/
install -m 0644 conf/crontab-slave $(DESTDIR)$(etcdir)/piuparts/
install -m 0644 conf/distros.conf $(DESTDIR)$(etcdir)/piuparts/
install -m 0644 instances/piuparts.conf.* $(DESTDIR)$(etcdir)/piuparts/
install -d $(DESTDIR)$(sharedir)/piuparts/slave
install -m 0755 update-piuparts-slave-setup $(DESTDIR)$(sharedir)/piuparts/slave/
install -d $(DESTDIR)$(sharedir)/piuparts/master
install -m 0755 update-piuparts-master-setup $(DESTDIR)$(sharedir)/piuparts/master/
install: build-stamp
install -d $(DESTDIR)$(sbindir)
install -m 0755 piuparts $(DESTDIR)$(sbindir)/
install -d $(DESTDIR)$(sharedir)/piuparts
install -m 0755 piuparts-slave piuparts-master piuparts-master-backend piuparts-report piuparts-analyze $(DESTDIR)$(sharedir)/piuparts/
install -d $(DESTDIR)$(site27)/piupartslib
install -m 0644 piupartslib/*.py $(DESTDIR)$(site27)/piupartslib/
install -d $(DESTDIR)$(sharedir)/piuparts/lib
install -m 0644 lib/*.sh $(DESTDIR)$(sharedir)/piuparts/lib/
# do not install the templates (*.in, *.py)
install -d $(DESTDIR)$(sharedir)/piuparts/master
install -m 0755 $(filter-out %.in %.py,$(wildcard master-bin/*)) $(DESTDIR)$(sharedir)/piuparts/master/
install -d $(DESTDIR)$(sharedir)/piuparts/known_problems
install -m 0644 known_problems/*.conf $(DESTDIR)$(sharedir)/piuparts/known_problems/
# do not install the templates (*.in, *.py)
install -d $(DESTDIR)$(sharedir)/piuparts/slave
install -m 0755 $(filter-out %.in %.py,$(wildcard slave-bin/*)) $(DESTDIR)$(sharedir)/piuparts/slave/
install -d $(DESTDIR)$(htdocsdir)
install -m 0644 htdocs/*.* $(DESTDIR)$(htdocsdir)/
install -d $(DESTDIR)$(htdocsdir)/images
install -m 0644 htdocs/images/*.* $(DESTDIR)$(htdocsdir)/images/
install -d $(DESTDIR)$(htdocsdir)/templates/mail
install -m 0644 bug-templates/*.mail $(DESTDIR)$(htdocsdir)/templates/mail/
install -d $(DESTDIR)$(etcdir)/piuparts
@set -e -x ; \
for d in $$(ls custom-scripts) ; do \
install -d $(DESTDIR)$(etcdir)/piuparts/$$d ; \
install -m 0755 custom-scripts/$$d/* $(DESTDIR)$(etcdir)/piuparts/$$d/ ; done
#install -d $(DESTDIR)$(etcdir)/piuparts/known_problems
#install -m 0644 known_problems/*.conf $(DESTDIR)$(etcdir)/piuparts/known_problems/
check:
nosetests --verbose
clean:
rm -f build-stamp
rm -f $(DOCS_GENERATED)
rm -f piuparts.1.xml README.xml README_server.xml docbook-xsl.css piuparts.html
rm -f *.pyc piupartslib/*.pyc master-bin/*.pyc slave-bin/*.pyc tests/*.pyc
rm -f $(SCRIPTS_GENERATED)
# for maintainer convenience only
tg-deps:
tg summary --graphviz | dot -T png -o deps.png
xli deps.png &
piuparts-0.64ubuntu1/piuparts-master.in 0000775 0000000 0000000 00000002437 12452567512 015240 0 ustar #!/bin/sh
set -e
# Copyright © 2013 Andreas Beckmann (anbe@debian.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# wrapper for running piuparts-master-backend without needing to know
# anything about the master setup and paths
#
. @sharedir@/piuparts/lib/read_config.sh
get_config_value MASTER global master-directory
get_config_value PYTHONPATH global PYTHONPATH ''
get_config_value LOGFILE global log-file master-error.log
export PYTHONPATH
LOGFILE="$LOGFILE.$$"
# put logfile in a deterministic location
cd "$MASTER"
trap "test -s ${LOGFILE} || rm -f ${LOGFILE}" EXIT
timeout 15m @sharedir@/piuparts/piuparts-master-backend 2> "$LOGFILE"
piuparts-0.64ubuntu1/update-piuparts-master-setup 0000775 0000000 0000000 00000005252 12452567512 017247 0 ustar #!/bin/sh
set -e
#
# update piuparts master setup from git (eg. used on pejacevic.debian.org)
#
# Copyright 2009-2013 Holger Levsen (holger@layer-acht.org)
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
if [ "`id -n -u`" != "piupartsm" ] ; then
echo please run this script as piupartsm user
exit 1
fi
PIUPARTS_PREFIX=/srv/piuparts.debian.org
PIUPARTS_HTDOCS=$PIUPARTS_PREFIX/htdocs
PIUPARTS_TMPDIR=$PIUPARTS_PREFIX/tmp
#
# create $PIUPARTS_PREFIX
#
if [ ! -d $PIUPARTS_PREFIX ] ; then
sudo mkdir -p $PIUPARTS_PREFIX
sudo chown piupartsm:piuparts $PIUPARTS_PREFIX
sudo chmod 0775 $PIUPARTS_PREFIX
fi
#
# update source
#
if [ ! -d $PIUPARTS_PREFIX/src ] ; then
mkdir -p $PIUPARTS_PREFIX/src
chmod 0755 $PIUPARTS_PREFIX/src
cd $PIUPARTS_PREFIX/src
git clone git://git.debian.org/git/piuparts/piuparts.git
cd piuparts
git checkout develop
fi
cd $PIUPARTS_PREFIX/src/piuparts
pwd
# git checkout branch if $1 is given
if [ ! -z "$1" ] ; then
git checkout $1
fi
# git fetch+pull if $2 is given
if [ ! -z "$2" ] ; then
git fetch $2
git pull $2 $1
fi
#
# install everything from GIT into PIUPARTS_PREFIX
#
make clean
make prefix=$PIUPARTS_PREFIX \
build build-doc
make prefix=$PIUPARTS_PREFIX \
docdir=$PIUPARTS_HTDOCS/doc \
htdocsdir=$PIUPARTS_HTDOCS \
install install-doc install-conf-4-running-from-git
make clean
#
# install copies of the weather icons
# to avoid needing FollowSymlinks in the apache config
#
for icon in weather-severe-alert.png sunny.png
do
if [ -e /usr/share/icons/Tango/24x24/status/$icon ] ; then
cp -f /usr/share/icons/Tango/24x24/status/$icon $PIUPARTS_HTDOCS/images/$icon
fi
done
#
# update $PIUPARTS_PREFIX
#
cd $PIUPARTS_PREFIX
pwd
mkdir -p master backup
# to support multiple hosts with this setup
cd etc/piuparts
HOSTNAME=$(hostname)
for f in piuparts.conf
do
ln -sf $f.$HOSTNAME $f
done
#
# create working dir
#
mkdir -p $PIUPARTS_TMPDIR
#
# update master home
#
cd
pwd
ln -sf $PIUPARTS_PREFIX/share/piuparts/master bin
crontab $PIUPARTS_PREFIX/etc/piuparts/crontab-master
echo "Update finished."
piuparts-0.64ubuntu1/htdocs/ 0000775 0000000 0000000 00000000000 12517712417 013021 5 ustar piuparts-0.64ubuntu1/htdocs/index.tpl 0000664 0000000 0000000 00000074205 12517712417 014661 0 ustar
About piuparts.debian.org
|
piuparts is a tool for testing that .deb packages can be installed, upgraded, and removed without problems.
piuparts is short for "package installation,
upgrading and removal testing suite" and is
a variant of something suggested by Tollef Fog Heen.
|
It does this by creating a minimal Debian installation in a chroot, and installing,
upgrading, and removing packages in that environment, and comparing the state of the directory tree before and after.
piuparts reports any files that have been added, removed, or modified during this process.
piuparts is meant as a quality assurance tool for people who create .deb packages to test them before they upload them to the Debian package archive.
|
A quick introduction is available in the piuparts README, and all the options are listed on the piuparts manpage.
|
To make sure piuparts is run on all packages in Debian, piuparts.debian.org has been set up to run piuparts in master/slave mode. This setup currently consists of two hosts: pejacevic.debian.org and piu-slave-bm-a.debian.org:
- pejacevic acts as the piuparts-master, which is responsible for scheduling test jobs to the slaves. The other main task is to generate the reports which are served via https://piuparts.debian.org.
- piu-slave-bm-a runs four piuparts-slave instances, which then run piuparts itself.
These hosts run as virtualized hardware on this nice cluster hosted at Bytemark.
|
To learn more about this setup, follow the "Documentation" links in the navigation menu on the left. Read those READMEs. The piuparts configuration for all the different suite(-combination)s that are currently being tested is also linked there.
|
Besides all the information provided here, there is some more information available on wiki.debian.org:
|
You can talk to us on #debian-qa on irc.debian.org (OFTC) or send an email on the piuparts development mailinglist. The best ways to contribute are to provide patches via GIT pull requests and/or to file bugs based on piuparts runs.
|
These pages are updated every six hours.
|
|
News
|
2015-04-25 With the release of Jessie two new suites are being tested: jessie2stretch and stretch, which will become the next Debian release.
|
2015-02-04 Link to the new Debian Package Tracker (tracker.debian.org) instead to the old Package Tracker System (PTS).
|
2015-01-24 Another suite was added: jessie-rcmd, to test installations in jessie with --install-recommends.
|
2014-12-19 Two more new suites were added: jessie-pu, to only test packages in jessie-proposed-updates and wheezy2jessie-rcmd, to test package upgrades from wheezy to jessie with --install-recommends.
|
2014-12-05 In preparation of the jessie release, another new suite was added: jessie2proposed, testing installation in jessie, then upgrade to jessie-proposed-upgrades, ending in purge as usual. Web pages are now updated four times a day.
|
2014-05-30 Results from debsums on wheezy2jessie and wheezy2bpo2jessie are not being ignored anymore as #744398 has been fixed.
|
2014-05-22 Add squeeze-lts to the distros being testing (by testing squeeze2squeeze-lts upgrades).
|
2014-05-19 Add a graph to the startpage showing the number of RC and non-RC bugs filed due to running piuparts.
|
2014-05-11 Temporarily ignore debsums results for wheezy2jessie and wheezy2bpo2jessie due to #744398.
|
2014-02-26 A new JSON summary file is being published, showing package testing state, status URL, and the number of packages being blocked by failures, for each distribution.
|
2013-07-16 To better track bugs in piuparts.debian.org and piuparts itself, a new pseudo-package was created in the BTS: piuparts.debian.org, which will be used for tracking all issues with the piuparts.debian.org service.
|
2013-06-05 In preparation of the first wheezy point release, another new suite was added: squeeze2wheezy-proposed, testing installation in squeeze, then upgrade to wheezy-proposed-upgrades, ending in purge as usual.
|
2013-05-30 Another new suite added: wheezy2proposed, testing installation in wheezy, then upgrade to wheezy-proposed-upgrades, ending in purge as usual.
|
2013-05-29 Another new suite added: squeeze2bpo-sloppy, testing the upgrade from squeeze to squeeze-backports-sloppy, ending in purge as usual.
|
2013-05-22 The webpages served by https://piuparts.debian.org are updated twice a day now. Further changes which were applied last week: debsums failures have been reenabled, adequate is now run by piuparts (see #703902) and two new suites were added: experimental and sid-nodoc, which tests sid without files in /usr/share/doc/<package>.
|
2013-05-14 Thanks to the new "hardware", piu-slave-bm-a is running four slaves now. Plus, these slaves are also considerably faster than piatti. And there are two new suites being tested: wheezy2jessie and wheezy2bpo2jessie - whoohoo!
|
2013-05-13 piuparts.debian.org has been moved to a new hardware and hosting location, now running virtualized on this nice cluster at Bytemark. Thanks to the Debian System Administrators for their assistence in setting up the host and maintaining the Debian infrastructure! Also many thanks and kittos to the Department of Computer Science at the University of Helsinki, Finland, for hosting piatti.debian.org since 2006 (at least)! For maintaining this setup we used the *bikeshed* git branch.
|
2013-03-15 Among many other new features the 0.50 release offers much greater flexibility for configuring and selecting (partial) suites and different mirrors.
Therefore it is possible to test nearly arbitrary upgrade pathes. On piuparts.debian.org this is now used for testing squeeze2bpo2wheezy and sid2experimental. Thanks to Andreas Beckmann for this great new feature!
|
2013-03-02 While the piuparts.git repo on Alioth will continue to be the main repo, there is also a piuparts clone on github, for those who prefer to send pull requests that way.
|
2012-06-21 piuparts 0.45 has been released, featuring piuparts-master and piuparts-slave packages to ease installation of such a setup. If you run piuparts in master/slave mode, please let us know.
|
2012-06-04 Wheezy freeze is approaching and lots of uploads happening. Old piatti hardware has problems keeping up with the pace of uploads, number of packages and distros being tested! :-) Piatti is about six years old...
|
2012-03-31 Disable lenny2squeeze tests, as lenny has been archived.
|
2012-03-05: temporarily disabled this again until we've sorted out problems with it.
2012-02-20: piuparts-analyse now sends commands the BTS: if a bug has not been explicitly marked fixed in the new version, it can rather very savely be assumed it's still present.
|
2012-01-30: Add new suite to be tested, testing2sid, to catch upgrade problems before they reach testing.
|
2012-01-22: Since some weeks, piuparts-analyse is captable of moving logfiles from fail to bugged, if there is a bug report usertagged 'piuparts' against that package+version combination. Thus, since today there is a webpage, explaining how to file bugs based on tests run on piuparts.debian.org. So now the question how to help can easily be answered: read that page and start filing bugs!
|
2012-01-20: As squeeze2wheezy has been fully tested by today, re-enable rescheduling of old logs for sid, wheezy and squeezewheezy: 200 successful logs older than 90 days are rescheduled each day, plus 25 failed logs older than 30 days.
|
2011-12-20: Currently, while the machine is busy testing all of squeeze2wheeezy, all old log rescheduling has been disabled. Normally, these reschedulings happen for sid, wheezy and squeezewheezy: 200 successful logs old than 180 days are rescheduled each day, plus 25 failed logs older than 30 days.
|
2011-12-10: Finally, upgrades from squeeze to wheezy are also being tested. Yay!
|
2011-11-21: All mails created by the piuparts master-slave setup on piatti.d.o are now sent to the piuparts-reports mailinglist on alioth. Subcribe and learn more about the details of this setup!
|
2011-10-31: Re-create base.tgz's every week now, as they will only be replaced if the recreation was successful.
|
2011-10-23: piuparts.debian.org is now maintained in git, using the piatti branch.
|
2011-07-10: Since today dpkg is run with --force-unsafe-io by for all suites except lenny2squeeze, as dpkg from lenny doesn't support this option.
|
2011-07-10: systemd-sysv is the eighth package getting special treatment by piuparts as it needs removal of sysvinit before installation and installation of that package before removal...
|
2011-04-02: New daily cronjob to reschedule the oldest 200 logfiles of each sid and wheezy, if they are older then 180 days. IOW: make sure no logfile for sid and wheezy is older than half a year.
|
2011-02-22: piatti.debian.org has been upgraded to squeeze.
|
2011-02-07: Add wheezy! Whoohoo! For now, the Wheezy distribution has just been added with the same testing options as Squeeze. In future, squeeze and lenny2squeeze will not be tested anymore, and squeeze2wheezy will also be added...
|
2011-01-25: Reschedule 27655 successfully tested packages in Squeeze, since they were tested before the deep freeze. Yesterday all 70 failed and bugged packages were rescheduled too, which surprisingly led to 6 successful tests, followed by a few more dependent packages also being tested.
|
2011-01-15: Reschedule 10123 successful and failed logs in lenny2squeeze for re-testing. Those are logs which have been tested before Squeeze was deep frozen or while there was still a bug in piuparts-slave, see last news entry for details.
|
2011-01-03: Reschedule 12306 successful and 8 bugged logs in lenny2squeeze for re-testing. Those are logs older than 148 days, which refers to when Squeeze was initially frozen (2010-08-06). Deep freeze was announced on 2010-12-13 and there are 3800 logs older then that too, but for future deletions it's better to use 2010-01-03 (=commit r857), which fixes a bug in piuparts-slave resulting in using the sid packages file for lenny2squeeze tests.
|
2010-11-28: debconf-english is the seventh package getting special treatment by piuparts: before removal, debconf-i18n is installed (see #539146 has the details and the news entry for 2010-11-25 lists the other six packages.)
|
2010-11-26: Schedule all 159 failed packages in lenny2squeeze for re-testing.
|
2010-11-25: Treat six packages specially: sudo (sensibly refuses removal if no root password is set), apt-listbugs (is called by apt and exists if there are RC buggy packages being upgraded), fai-nfsroot, ltsp-client-core (these two packages modify the installed system heavily and thus will only install if conditions are met), file-rc and upstart (these two replace essential packages and therefore apt needs to be told to do this).
|
2010-11-24: Disable the logrotate test until #582630 is fixed and reschedule all 51 packages in sid failed due to it.
|
2010-11-14: Schedule all 402 failed packages in sid for re-testing.
|
2010-11-12: Schedule all 108 failed packages in squeeze for re-testing. (Followup on 2010-09-04.)
|
2010-11-06: The lists of known circular depends is now taken from http://debian.semistable.com/debgraph.out.html and maintained separately (and manually) for each tested distribution in piuparts.conf - this is not optimal (which would be piuparts detecting them automatically) but much better than the hardcoded list which we had in the piuparts library since December 2009.
|
2010-09-04: Schedule all 27438 passed packages in squeeze for re-testing now that squeeze is frozen.
|
2009-07-24: #531349 has been fixed, piuparts results are now displayed in the PTS.
|
2010-05-18: From today on, broken logrotate scripts after purge are only reported in sid.
|
2010-05-16: Finally enabled testing of sid again. (Actually, sid was enabled on 2010-03-05, but piuparts.d.o was broken until today.)
|
2010-02-28: Due to #571925 testing of sid had to be disabled temporarily. On an unrelated note, testing of lenny2squeeze still has some issues atm...
|
2010-02-25: Since yesterday, squeeze and lenny2squeeze are being tested with "--warn-on-leftovers-after-purge" making piuparts only warn about leftover files after purge. This has two effects: an decrease in the number of failed logs to process, to better focus on more important problems and second, more packages will be tested, as less packages are (seen as) buggy. Today all failed packages in squeeze and lenny2squeeze have been rescheduled for testing.
|
2010-02-23: Since today, piuparts is able to detect broken logrotate scripts after purge, which will need retesting of all successfully tested packages eventually. The failed packages in squeeze also needs retesting, due to split into squeeze and lenny2squeeze last week.
|
2010-02-16: The squeeze test has been split into squeeze and lenny2squeeze, where squeeze means package installation in squeeze, removal and purge test, while lenny2squeeze means package installation in lenny, then upgrade to squeeze, then removal and purge test. This allows more issues to be found in squeeze since (potential) brokeness in lenny is not blurring the results in squeeze.
|
2010-01-05: Reschedule testing for 319 failed packages in sid and 544 in squeeze, since --warn-on-others is now used.
|
2009-12-24: Enable work-in-progress code to enable testing of packages with circular depends. This will allow testing of 5-6000 more packages in sid and squeeze, see #526046 and the 0.39 changelog for details. The list of packages with circular depends is currently hard-coded and will probably become a configuration option but not auto detected. But that's code yet to be written :-)
|
2009-12-21: So testing of 13398 in squeeze has taken 12 days, which is no big surprise as the squeeze tests are more complex. Today 499 failed packages from sid and 235 from squeeze have been rescheduled for testing, to catch broken symlinks in those too.
|
2009-12-12: After testing 14416 packages in sid in three days, reschedule 15944 packages in squeeze... see previous entry for an explanation why.
|
2009-12-09: Reschedule testing for 14287 successfully tested packages in sid, those in squeeze will be rescheduled once all testable package in sid have been tested again. This is because piuparts now creates and maintains chroots securily (using gpg signed Release files for both debootstrap and apt-get) and because it warns if broken symlinks are found in a package.
|
2009-12-05: Reschedule testing for ~400 failed packages in sid and ~600 in squeeze, to be followed by a rescheduling of all successful packages. This is because piuparts now warns if broken symlinks are found in a package.
|
2009-10-08: Reschedule testing for ~2000 failed packages in sid, which failed because of a problem when minimizing the chroot at the beginning of the piuparts tests. As of today, piuparts running on piuparts.debian.org does not minimize the chroots anymore.
|
2009-09-18: Reschedule testing for 17170 (successfully tested) packages in sid, to make sure they still install fine with dependency based booting enabled now in sid. Throwing away 42806 (successful) logfiles from those packages :-)
|
2009-09-16: Reschedule testing for 233 failing packages in sid which were affected by #545949. No packages in squeeze were affected.
|
2009-06-20: Failed logs are not grouped into (at the moment) seven types of known errors and one type of issues is detected in successful logs.
|
2009-06-06: Reschedule testing for 163 successful and 27 failing packages in sid which were affected by #530501. Once openssh 1:5.1p1-6 has reached squeeze, this will be done again with 194 packages there.
|
2009-05-27: Throw away all failed logs as there was a bug in piuparts leading to use a more uptodate mirror for getting the list of available packages and another for doing the tests. This lead to at least one fixed package which was incorrectly tested as failing, as an old version of the package was tested. To rule out some false positives about 1000 packages will be retested, but on this machine this will only take about a day :-)
|
2009-05-11: Filed #528266 and made piuparts ignore files in /tmp after purge. This got rid of 20 failures in sid and 14 in squeeze.
|
2009-05-06: Only believe statistics you faked yourself! Up until today piuparts used to include virtual packages (those only exist true the Provides: header) into the calculations of statistics of package states and the total number of packages. Suddenly, sid has 2444 packages less!
|
2009-05-01: All packages in squeeze and sid which can be tested have been tested. So it takes about one month to do a full piuparts run against one suite of the archive on this machine, that's almost 1000 packages tested per day.
|
2009-04-20: Deleted 86 more failed logfiles (out of 692 failures in total atm) which were due to broken packages, which most likely are temporarily uninstallable issues - a good indicator for this is that all of those failures happened in sid and none in squeeze. For the future there is a cronjob now, to notify the admins daily of such problems. In more distant future those issues should be detected and avoided.
|
2009-04-18: Deleted all 14 failed logfiles which complained about /var/games being present after purge, as this ain't an issue, see #524461.
|
2009-04-04: Deleted all failed logfiles so far for two reasons: until now, only three out of ten failure types where logged with a pattern to search for in the logfiles, now this is done for all ten types of failures. And second, the way of breaking circular dependencies was not bulletproof, thus there were false positives in the failures. Now it should be fine, though maybe this will lead to lots of untestable packages... we'll see.
|
2009-03-19: lenny2squeeze is not needed, so all logs for squeeze (as well as lenny2squeeze) were deleted. (As squeeze now includes two kinds of tests: installation and removal in squeeze, and installation in lenny, upgrade to squeeze, removal in squeeze.)
|
2009-02-28: Start maintaining piatti.debian.org via the piuparts svn repository on alioth.
|
2007-02-24: Holger puts piuparts source in svn.
|
2006-10-02: #390754 O: piuparts -- package installation, upgrading and removal testing tool"
|
2006-09-29: Lars seeks help maintaining piuparts.
|
2005-07-05: #317033 ITP: piuparts -- .deb package installation, upgrading, and removal testing tool
|
2005-06-19: Lars writes the first blog post about piuparts (version 0.4).
|
piuparts-0.64ubuntu1/htdocs/robots.txt 0000664 0000000 0000000 00000000037 12452567512 015074 0 ustar User-agent: *
Disallow: /fail/
piuparts-0.64ubuntu1/htdocs/bug_howto.tpl 0000664 0000000 0000000 00000010601 12452567512 015537 0 ustar
How to file bugs based on tests run on piuparts.debian.org
|
This page shall grow into a well written explaination how to file useful bugs fast. It assumes you are familar with reporting bugs in Debian.
|
First, of all, read the piuparts logfile and identify why piuparts testing failed.
|
Then, check the BTS for that package, to see if this issue was already filed as a bug. Often it's also useful to check the source packages bug page. Sometimes a bug already exists, describing the problem piuparts has found. More often, new bugs have to be filed.
|
Usertagging existing bugs to make them known to piuparts.debian.org
|
If there already is a bug describing the same problem you're seeing in the piuparts logfile, you can usertag it, so that the next piuparts-analyse run will be able to link the bug report with the logfile on piuparts.debian.org. (piuparts-analyse runs twice a day.)
User: debian-qa@lists.debian.org
Usertags 987654 + piuparts
|
Filing new bugs
|
More often, there is no existing bug and you need to file one. To make this easy as well to have consistent quality bug reports, we collect templates for filing these bugs. Please use these templates! The following is an example bug report for illustration:
|
To: submit@bugs.debian.org
Subject: $package: fails to upgrade from 'testing' - trying to overwrite ...
Package: $package
Version: $version
Severity: serious
User: debian-qa@lists.debian.org
Usertags: piuparts
Hi,
during a test with piuparts I noticed your package fails to upgrade from
'testing'. It installed fine in 'testing', then the upgrade to 'sid'
fails because it tries to overwrite other packages files without
declaring a replaces relation.
See policy 7.6 at
https://www.debian.org/doc/debian-policy/ch-relationships.html#s-replaces
From the attached log (scroll to the bottom...):
$useful_except_from_logfile
cheers,
$your_name
attachment: $failed_logfile
|
Please take care when filing bugs to file meaningful bugs and to not annoy maintainers. Don't nitpick or insist on severities, the important thing is to get the bug fixed, not the right severity. Optionally you can also send copies to the piuparts-devel mailinglist by adding X-debbugs-cc: piuparts-devel@lists.alioth.debian.org pseudo-headers.
|
Also, you should be aware that what you are doing can probably be seen as mass bug filing (even if you just file a few now, they are part of a series of bugs of one kind) and as such needs to be discussed on debian-devel@lists.d.o first! For many types of bugs this has already been done. This is or should be indicated in the summary web pages as well as the mail templates.
|
Marking bugs as affecting other packages
|
Sometimes there is a bug in another package which affects a package being tested. The following explains how to tell this to the BTS in a way piuparts-analyse will pick up:
|
# assume 987654 is our bug report in buggy-package,
# but the problem only shows up when testing (upgrades of)
# failing-package with piuparts:
bts affects 987654 failing-package
# and if failing-package is from a different source with a different
# version number:
bts found 987654 failing-package/$FAILED_VERSION
|
piuparts-0.64ubuntu1/htdocs/style.css 0000664 0000000 0000000 00000011560 12452567512 014700 0 ustar #main {
border: none;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 10px;
padding-right: 10px;
vertical-align: top;
background-color: #ddd;
}
hr {
width: 100%;
color:#d70751;
background-color:#d70751;
height:2px;
margin: 0px;
padding: 0px;
}
em {
font-weight: bold;
}
p.note {
font-family: sans-serif;
color: #900;
text-align: center;
padding: 5px;
font-size: 11px;
font-weight: normal;
}
div.c1 {text-align: center}
p.text {
font-family: sans-serif;
padding: 5px;
font-weight: normal;
}
body {
padding: 0px;
margin: 0px;
font-family: sans-serif;
font-size: 90%;
color: #000000;
background-color: white;
}
#obeytoyourfriend
{
color: #000;
background-color: white;
border: 0px solid #000;
border-collapse: collapse;
margin-top: 0px;
margin-bottom: 5px;
padding-top: 0px;
padding-left: 15px;
font-family: serif;
font-variant:small-caps;
font-size: 140%;
}
p.validate {
text-align: center;
}
table
{
color: #000;
background-color: #000;
border: 0px solid #000;
border-collapse: separate;
border-spacing: 1px;
}
h1 {
font-size: 140%;
text-align: center;
color: #000;
}
h2 {
font-size: 120%;
text-align: center;
color: #000;
}
h3 {
font-size: 110%;
text-align: center;
color: #000;
}
p {
font-size: 100%;
text-align: justify;
}
tr {
background-color: #FFF;
}
tr.odd {
background-color: #FFFFFF;
}
tr.even {
background-color: #e8e8e8;
}
td.sid {
color: #000;
text-align: left;
}
tr.experimental {
color: #cc0000;
}
tr.unstable {
color: #345677;
}
tr.sid_odd {
color: #000;
}
td.exp {
color: #cc0000;
text-align: left;
}
tr.exp_odd {
color: #900;
}
th {
font-size: 120%;
text-align: center;
font-weight: bold;
background-color: #BDF;
border: 0px solid #000;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 6px;
padding-right: 6px;
}
th.reject {
font-size: 120%;
text-align: center;
font-weight: bold;
background-color: #BDF;
border: 0px solid #000;
padding-top: 10px;
padding-bottom: 10px;
padding-left: 6px;
padding-right: 6px;
}
td {
font-size: 100%;
border: 0px solid #000;
padding: 4px;
padding-left: 6px;
padding-right: 6px;
}
a.needs-bugging {
background-color:#e0c0d0;
}
span.needs-bugging {
background-color:#e0c0d0;
}
#needs-bugging {
background-color:#e0c0d0;
}
a.bugged {
background-color:#c0c0f0;
}
a:link {
color: #0000FF;
text-decoration: none;
}
a:visited {
color: #800080;
text-decoration: none;
}
a:active {
color: #FF0000;
text-decoration: none;
}
a:hover {
color: #0000FF;
text-decoration: underline;
}
#header {
padding: 3px;
}
h1.header {
font-size: 32px;
text-align: left;
margin-bottom: 0px;
margin-top: 0px;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 15px;
}
#footer {
padding: 15px;
font-size: 90%;
text-align: center;
}
/* the following layout is taken from the PTS */
/* Tables */
table.containertable {
clear: both;
background-color: #ddd;
border: none;
}
table.lefttable {
width: 100%;
border-collapse: collapse;
border: 2px solid black;
background-color: white;
color: black;
}
table.righttable {
width: 100%;
border-collapse: collapse;
border: 2px solid black;
background-color: white;
color: black;
}
td.containercell {
background-color: #ddd;
}
td.titlecell {
color: white;
background-color: #d70751;
font-weight: bold;
text-align: center;
padding: 0.2em 0.2em 0.1em 0.2em;
border-top: 3px solid #999;
border-bottom: 1px solid #999;
}
td.alerttitlecell {
color: white;
background-color: #0755d7;
font-weight: bold;
text-align: center;
padding: 0.2em 0.2em 0.1em 0.2em;
border-top: 3px solid #999;
border-bottom: 1px solid #999;
}
td.labelcell {
vertical-align: top;
text-align: left;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
font-weight: bold;
}
td.alertlabelcell {
color: white;
background-color: #0755d7;
vertical-align: top;
text-align: left;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
font-weight: bold;
}
td.lightalertlabelcell {
color: white;
background-color: #90c0ff;
vertical-align: top;
text-align: left;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
font-weight: bold;
}
td.labelcell2 {
padding: 0.2em 0.2em 0.1em 0.2em;
border-top: 1px solid black;
border-right: 1px dotted black;
font-weight: bold;
}
td.contentcell {
text-align: center;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
}
td.lastcell {
font-size: 80%;
text-align: center;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
}
td.contentcell2 {
text-align: left;
vertical-align: top;
padding: 0.2em 0.3em 0.2em 0.3em;
border-bottom: 1px dotted #999;
border-right: 1px dotted #999;
}
piuparts-0.64ubuntu1/htdocs/images/ 0000775 0000000 0000000 00000000000 12452567512 014270 5 ustar piuparts-0.64ubuntu1/htdocs/images/debian.png 0000664 0000000 0000000 00000007467 12452567512 016236 0 ustar PNG
IHDR = i pHYs H H Fk> IDATx tMǟJ%!5 b-U
AKi"]J4֩RGH֒-bH,HOwry^4y;sg3ej^Z*$X@_)zo+V`%ہﴒa<{̂Pb"~x")))00kJ߷o}qq(pFFNNÇϟߪU+k6l٪ɓ͛WZUE2^)~|ʪY1t~~mMI7{߾};22ryժUަM]N2eGh(dӽV={.jQ\Msc!<g%ر"d.G}dj2 p&d6m%*.E'MTT>,,F^Ph_c&;o:d͵!>j(u"l|QfB2b)2 yv>,!cʔ)$Cf#xeD.%ԩSf9Hk;친##//'*V2?[{J+2Y|KQ\\gqJ2$C233y~7@?T`_t{Çuk>uV=z$.EVL]:u*mUVyyy'RA6lIFaa![еozt;wGmoooggfӧ,Y2tP2S͚5}||-[v9}AAO-XI&
cU.\
rrr"!Ųx@O888h6<9s|(...[l1gϺ3Ezt!<|т#Fٳgztuuu0n8tMקO'N0Zɓx`J&E2L2RV{*[l1Zd@կ__1&䝧Hʢ͓Jۛ ֭$}QQ}*I
hFAP#,1gq˗ߵkTXx,{=h]b%lX}^dpb!Ȑ!CqFQv48Ќ2(zUz[nHJJT*UJ -fbb"'l#"r=M$A&O,7VRQuvv6Ȉ48he[\h~;>Q[J&
uC
hx/^<|UN2 fbn7L66h```Æ
%T
V1}t(ƣkIܹs)aw$얃O Ehd$''KA8q=FcFF@@ mX
F >#
%xVĤ͚5C'1?FtŴa݈:\Au'owezQhJ]3f?0b8::~(oߞ?ʍ7O!\bMGaKE9ɘ3gq@<}A=6d˫`_%,]_asQϜBBx9/Cc!F=a__~Q;DM|ڵ;~80UwUF,*7(~.]شi1=Ñ=ݙ1MWd d
"ؙG8]&j7|C{H2'EơCrt #((K{CȞW8!1aE2`AD"gkԨ!f ~P}ˢ5%ܹ^ Aܓ?їHF3hKV@ƶmT!Ɔ=$ȀPrebHN:O=y*zf#f%bY~~~
d .bڵksGb_|d8;;+P1sd)66,$$pL,?dt&n&