Merge lp:~mvo/unattended-upgrades/lp1061498 into lp:~mvo/unattended-upgrades/debian-sid-mirror

Proposed by Michael Vogt
Status: Needs review
Proposed branch: lp:~mvo/unattended-upgrades/lp1061498
Merge into: lp:~mvo/unattended-upgrades/debian-sid-mirror
Diff against target: 1912 lines (+457/-270)
23 files modified
.bzrignore (+2/-0)
debian/changelog (+23/-2)
debian/control (+5/-4)
debian/rules (+13/-11)
debian/tests/control (+2/-0)
debian/tests/run-tests (+4/-0)
debian/unattended-upgrades.init (+1/-1)
pm/sleep.d/10_unattended-upgrades-hibernate (+1/-1)
setup.py (+4/-3)
test/Makefile (+9/-2)
test/create_debug_lock.py (+2/-1)
test/test_against_real_archive.py (+14/-4)
test/test_conffile.py (+29/-6)
test/test_in_chroot.py (+41/-34)
test/test_logdir.py (+3/-2)
test/test_mail.py (+33/-16)
test/test_minimal_partitions.py (+9/-9)
test/test_origin_pattern.py (+31/-15)
test/test_pep8.py (+17/-0)
test/test_pyflakes.py (+4/-2)
test/test_substitute.py (+2/-7)
unattended-upgrade (+205/-147)
unattended-upgrade-shutdown (+3/-3)
To merge this branch: bzr merge lp:~mvo/unattended-upgrades/lp1061498
Reviewer Review Type Date Requested Status
Michael Vogt Pending
Review via email: mp+128271@code.launchpad.net

Description of the change

Fix crash #1061498 and add test

To post a comment you must log in.

Unmerged revisions

303. By Michael Vogt

fix dpkg_conffile_prompt() LP: #1061498 and add testcase

302. By Michael Vogt

test/Makefile: fix cleanup

301. By Michael Vogt

debian/tests/run-tests: add run-test script

300. By Michael Vogt

add dep8 tests

299. By Michael Vogt

Fixed debug output when a package has no candidates (LP: #1046438)

298. By Michael Vogt

releasing version 0.79.3ubuntu1

297. By Michael Vogt

fully pep8 clean (yeah!)

296. By Michael Vogt

add pyflakes/pep8 tests

295. By Michael Vogt

add py2 compatiblity back for easier backporting and run the tests in both py2/py3 and also run python-coverage

294. By Michael Vogt

add missing +x for mock_sendmail

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2012-10-05 14:59:30 +0000
4@@ -0,0 +1,2 @@
5+__pycache__
6+build
7
8=== modified file 'debian/changelog'
9--- debian/changelog 2012-08-14 13:04:45 +0000
10+++ debian/changelog 2012-10-05 14:59:30 +0000
11@@ -1,3 +1,24 @@
12+unattended-upgrades (0.79.3ubuntu2) quantal; urgency=low
13+
14+ [ Marc Tardif ]
15+ * Fixed debug output when a package has no candidates (LP: #1046438)
16+
17+ [ Michael Vogt ]
18+ * debian/test/:
19+ - add dep8 tests
20+
21+ -- Marc Tardif <marc@ubuntu.com> Thu, 13 Sep 2012 16:16:04 -0400
22+
23+unattended-upgrades (0.79.3ubuntu1) quantal; urgency=low
24+
25+ [ Thomas Kluyver ]
26+ * Port to Python 3
27+
28+ [ Brian Murray ]
29+ * unattended-upgrade: fix typo in debugging output
30+
31+ -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 10 Sep 2012 09:55:19 +0200
32+
33 unattended-upgrades (0.79.4) UNRELEASED; urgency=low
34
35 * data/50unattended-upgrades.{Debian,Ubuntu}:
36@@ -63,7 +84,7 @@
37 - added, thanks to Pedro Ribeiro, closes: #678738
38 * po/sk.po:
39 - added, thanks to helix84, closes: #677471
40-
41+
42 [ Teodor MICU ]
43 * debian/unattended-upgrades.init:
44 - fixes new style lsb-init output, closes: #678030
45@@ -93,7 +114,7 @@
46 - updated, thanks to Joe Dalton, closes: #677804
47 * po/de.po:
48 - updated, thanks to Chris Leick (closes: #678204)
49-
50+
51 [ Teodor MICU ]
52 * debian/unattended-upgrades.init:
53 - use new style lsb-init output, closes: #678030
54
55=== modified file 'debian/control'
56--- debian/control 2012-07-13 18:51:00 +0000
57+++ debian/control 2012-10-05 14:59:30 +0000
58@@ -3,14 +3,15 @@
59 Priority: optional
60 Maintainer: Michael Vogt <michael.vogt@ubuntu.com>
61 Build-Depends: debhelper (>= 7.0.50~), po-debconf, lsb-release
62-Build-Depends-Indep: python (>= 2.6.6-3~), python-distutils-extra
63-Standards-Version: 3.8.3
64+Build-Depends-Indep: python3, python3-distutils-extra
65+Standards-Version: 3.9.3
66 Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/unattended-upgrades/ubuntu/
67+XS-Testsuite: autopkgtest
68
69 Package: unattended-upgrades
70 Architecture: all
71-Depends: ${shlibs:Depends}, ${misc:Depends}, debconf, python,
72- python-apt (>= 0.7.90), apt-utils, apt, ucf, lsb-release,
73+Depends: ${shlibs:Depends}, ${misc:Depends}, debconf, python3,
74+ python3-apt (>= 0.7.90), apt-utils, apt, ucf, lsb-release,
75 lsb-base (>= 3.2-14)
76 Suggests: bsd-mailx, mail-transport-agent
77 Description: automatic installation of security upgrades
78
79=== modified file 'debian/rules'
80--- debian/rules 2011-11-09 19:20:50 +0000
81+++ debian/rules 2012-10-05 14:59:30 +0000
82@@ -3,24 +3,26 @@
83 DIST=$(shell /usr/bin/lsb_release -i -s)
84
85 %:
86- dh $@ --with python2
87+ dh $@ --with python3
88
89 override_dh_auto_build:
90 # copy the right template into place
91 cp data/50unattended-upgrades.$(DIST) data/50unattended-upgrades
92- dh_auto_build
93+ python3 setup.py build
94+
95+override_dh_auto_install:
96+ python3 setup.py install \
97+ --root=$(CURDIR)/debian/unattended-upgrades \
98+ --install-layout=deb
99
100 override_dh_auto_clean:
101 # Sanity-check before upload.
102- set -e; if [ -e /usr/lib/python$(PYVER)/py_compile.py ]; then \
103- for f in unattended-upgrade unattended-upgrade-shutdown; do \
104- ln -nsf $$f $$f.py; \
105- python$(PYVER) /usr/lib/python$(PYVER)/py_compile.py \
106- $$f.py; \
107- rm -f $$f.py; \
108- done; \
109- fi
110- dh_auto_clean
111+ set -e; for f in unattended-upgrade unattended-upgrade-shutdown; do \
112+ ln -nsf $$f $$f.py; \
113+ py3compile $$f.py; \
114+ rm -f $$f.py; \
115+ done
116+ python3 setup.py clean -a
117
118 override_dh_installinit:
119 # we do not want to run the init script in the postinst/prerm, its
120
121=== added directory 'debian/tests'
122=== added file 'debian/tests/control'
123--- debian/tests/control 1970-01-01 00:00:00 +0000
124+++ debian/tests/control 2012-10-05 14:59:30 +0000
125@@ -0,0 +1,2 @@
126+Tests: run-tests
127+Depends: @, make, python-dev, python3-dev, python-coverage
128
129=== added file 'debian/tests/run-tests'
130--- debian/tests/run-tests 1970-01-01 00:00:00 +0000
131+++ debian/tests/run-tests 2012-10-05 14:59:30 +0000
132@@ -0,0 +1,4 @@
133+#!/bin/sh
134+
135+cd test
136+make
137
138=== modified file 'debian/unattended-upgrades.init'
139--- debian/unattended-upgrades.init 2012-06-29 08:09:25 +0000
140+++ debian/unattended-upgrades.init 2012-10-05 14:59:30 +0000
141@@ -33,7 +33,7 @@
142 stop)
143 if [ -e $SHUTDOWN_HELPER ]; then
144 [ "$VERBOSE" != "no" ] && log_action_begin_msg "Checking for running $DESC"
145- python $SHUTDOWN_HELPER
146+ python3 $SHUTDOWN_HELPER
147 [ "$VERBOSE" != "no" ] && log_action_end_msg $? "$NAME"
148 fi
149 ;;
150
151=== modified file 'pm/sleep.d/10_unattended-upgrades-hibernate'
152--- pm/sleep.d/10_unattended-upgrades-hibernate 2011-11-08 16:56:58 +0000
153+++ pm/sleep.d/10_unattended-upgrades-hibernate 2012-10-05 14:59:30 +0000
154@@ -17,7 +17,7 @@
155 case "${1}" in
156 hibernate)
157 if [ -e $SHUTDOWN_HELPER ]; then
158- python $SHUTDOWN_HELPER
159+ python3 $SHUTDOWN_HELPER
160 fi
161 ;;
162 resume|thaw)
163
164=== modified file 'setup.py'
165--- setup.py 2011-10-24 10:20:18 +0000
166+++ setup.py 2012-10-05 14:59:30 +0000
167@@ -1,9 +1,10 @@
168 #!/usr/bin/env python
169
170 from distutils.core import setup
171-from DistUtilsExtra.command import *
172-import glob
173-import os
174+from DistUtilsExtra.command import (
175+ build_extra,
176+ build_i18n,
177+ )
178
179
180 setup(name='unattended-upgrades', version='0.1',
181
182=== modified file 'test/Makefile'
183--- test/Makefile 2011-10-07 09:22:19 +0000
184+++ test/Makefile 2012-10-05 14:59:30 +0000
185@@ -3,12 +3,15 @@
186 all: check
187
188 check:
189+ # test with both py2 and py3 for now and also use coverage for the py2
190 set -e; \
191 find . -name 'test_*.py' | \
192 while read file; do \
193- echo "Running $$file"; \
194 if [ -x $$file ]; then \
195- python $$file ; \
196+ echo "Running $$file with python3"; \
197+ python3 $$file ; \
198+ echo "Running $$file with python"; \
199+ python-coverage run -a $$file; \
200 fi \
201 done
202
203@@ -16,4 +19,8 @@
204 rm -rf ./aptroot/var/cache/
205 rm -rf ./aptroot/var/lib/apt
206 rm -rf ./aptroot/var/run
207+ find .. -type d -name __pycache__ | xargs rm -rf
208
209+coverage-html:
210+ echo "output in htmlcov/
211+ python-coverage html
212\ No newline at end of file
213
214=== modified file 'test/create_debug_lock.py'
215--- test/create_debug_lock.py 2011-06-16 07:10:07 +0000
216+++ test/create_debug_lock.py 2012-10-05 14:59:30 +0000
217@@ -1,4 +1,4 @@
218-#!/usr/bin/python
219+#!/usr/bin/python3
220 #
221 # create a lock file so that unattended-upgrades-shutdown pauses
222 # on shutdown -- useful for testing
223@@ -7,6 +7,7 @@
224 import os
225 import time
226
227+
228 pid = os.fork()
229 if pid == 0:
230 os.setsid()
231
232=== modified file 'test/test_against_real_archive.py' (properties changed: +x to -x)
233--- test/test_against_real_archive.py 2012-02-28 10:48:18 +0000
234+++ test/test_against_real_archive.py 2012-10-05 14:59:30 +0000
235@@ -1,22 +1,31 @@
236-#!/usr/bin/python
237+#!/usr/bin/python3
238+"""Test unattended_upgrades against the real archive in a chroot.
239+
240+Note that this test is not run by the makefile in this folder, as it requires
241+network access, and it fails in some situations (unclear which).
242+"""
243
244 import apt
245 import apt_pkg
246 import glob
247+import logging
248 import os
249 import re
250 import unittest
251
252 import unattended_upgrade
253
254+
255 apt_pkg.config.set("APT::Architecture", "amd64")
256
257+
258 class MockOptions():
259 def __init__(self, debug=True, dry_run=True):
260 self.debug = debug
261 self.dry_run = dry_run
262 self.minimal_upgrade_steps = False
263
264+
265 class TestAgainstRealArchive(unittest.TestCase):
266
267 def setUp(self):
268@@ -40,11 +49,13 @@
269 apt_pkg.config.set("APT::UnattendedUpgrades::LogDir", logdir)
270 unattended_upgrade.DISTRO_CODENAME = "lucid"
271 res = unattended_upgrade.main(options, os.path.abspath("./aptroot"))
272+ logging.debug(res)
273 # check if the log file exists
274 self.assertTrue(os.path.exists(logfile))
275- log = open(logfile).read()
276+ with open(logfile) as fp:
277+ log = fp.read()
278 # check that stuff worked
279- self.assertFalse(" ERROR " in log)
280+ self.assertFalse(" ERROR " in log, log)
281 # check if we actually have the expected ugprade in it
282 self.assertTrue(
283 re.search("INFO Packages that are upgraded:.*awstats", log))
284@@ -59,4 +70,3 @@
285
286 if __name__ == "__main__":
287 unittest.main()
288-
289
290=== modified file 'test/test_conffile.py'
291--- test/test_conffile.py 2012-06-28 20:06:37 +0000
292+++ test/test_conffile.py 2012-10-05 14:59:30 +0000
293@@ -1,11 +1,15 @@
294-#!/usr/bin/python
295+#!/usr/bin/python3
296
297 import apt_pkg
298 import logging
299 import unittest
300-import sys
301-
302-from unattended_upgrade import conffile_prompt
303+
304+
305+from unattended_upgrade import (
306+ conffile_prompt,
307+ dpkg_conffile_prompt,
308+ )
309+
310
311 class ConffilePromptTestCase(unittest.TestCase):
312
313@@ -19,7 +23,7 @@
314 test_pkg = "./packages/conf-test-package_1.1.deb"
315 self.assertTrue(conffile_prompt(test_pkg, prefix="./root.conffile"),
316 "conffile prompt detection incorrect")
317-
318+
319 def test_will_not_prompt(self):
320 # conf-test 0.9 is installed, 1.0 gets installed
321 # they both have the same config files
322@@ -52,9 +56,28 @@
323 test_pkg = "./packages/conf-test-package-new-conffile_1.deb"
324 self.assertTrue(conffile_prompt(test_pkg, prefix="./root.conffile"),
325 "conffile prompt detection incorrect")
326+
327+class DpkgConffileTestCase(unittest.TestCase):
328+ """
329+ This tests that the detection if dpkg will prompt at all works,
330+ i.e. if the user has decided to use a --force-conf{old,new} option
331+ """
332+
333+ def setUp(self):
334+ apt_pkg.config.clear("DPkg::Options")
335+
336+ def test_no_dpkg_prompt_option(self):
337+ self.assertTrue(dpkg_conffile_prompt())
338+
339+ def test_regression_lp1061498(self):
340+ apt_pkg.config.set("DPkg::Options::", "muup")
341+ self.assertTrue(dpkg_conffile_prompt())
342+
343+ def test_dpkg_will_never_prompt(self):
344+ apt_pkg.config.set("DPkg::Options::", "--force-confold")
345+ self.assertFalse(dpkg_conffile_prompt())
346
347
348 if __name__ == "__main__":
349 logging.basicConfig(level=logging.DEBUG)
350 unittest.main()
351-
352
353=== modified file 'test/test_in_chroot.py'
354--- test/test_in_chroot.py 2012-06-28 20:06:37 +0000
355+++ test/test_in_chroot.py 2012-10-05 14:59:30 +0000
356@@ -1,4 +1,4 @@
357-#!/usr/bin/python
358+#!/usr/bin/python3
359
360 import apt
361 import logging
362@@ -15,7 +15,8 @@
363 #SOURCES_LIST="""
364 #deb http://ftp.de.debian.org/debian squeeze main contrib non-free
365 #deb http://ftp.de.debian.org/debian squeeze-updates main contrib non-free
366-#deb http://ftp.de.debian.org/debian squeeze-proposed-updates main contrib non-f#ree
367+#deb http://ftp.de.debian.org/debian squeeze-proposed-updates main contrib \
368+# non-free
369 #deb http://security.debian.org squeeze/updates main contrib non-free
370 #"""
371 #DISTRO="squeeze"
372@@ -27,7 +28,7 @@
373
374
375 # ubuntu
376-SOURCES_LIST="""
377+SOURCES_LIST = """
378 deb http://archive.ubuntu.com/ubuntu/ lucid main restricted
379 deb-src http://archive.ubuntu.com/ubuntu/ lucid main restricted
380
381@@ -37,35 +38,39 @@
382 deb http://security.ubuntu.com/ubuntu/ lucid-security main restricted
383 deb-src http://security.ubuntu.com/ubuntu/ lucid-security main restricted
384 """
385-DISTRO="lucid"
386-ARCH="i386"
387-TARBALL="%s-%s.tgz" % (DISTRO, ARCH)
388-MIRROR="http://archive.ubuntu.com/ubuntu"
389-APT_CONF="""APT::Architecture "%s";""" % ARCH
390-ORIGINS_PATTERN="origin=Ubuntu,archive=lucid-security"
391+DISTRO = "lucid"
392+ARCH = "i386"
393+TARBALL = "%s-%s.tgz" % (DISTRO, ARCH)
394+MIRROR = "http://archive.ubuntu.com/ubuntu"
395+APT_CONF = """APT::Architecture "%s";""" % ARCH
396+ORIGINS_PATTERN = "origin=Ubuntu,archive=lucid-security"
397
398 apt.apt_pkg.config.set("APT::Architecture", ARCH)
399 sys.path.insert(0, "..")
400 import unattended_upgrade
401
402+
403 class MockOptions(object):
404 debug = True
405 dry_run = False
406 minimal_upgrade_steps = False
407
408+
409 class TestUnattendedUpgrade(unittest.TestCase):
410
411 def _create_new_debootstrap_tarball(self, tarball, target):
412- print "creating initial test tarball, this is needed only once"
413+ print("creating initial test tarball, this is needed only once")
414 # force i386
415- subprocess.call(["debootstrap",
416- "--arch=%s" % ARCH,
417- # smaller version of the minimal system
418- "--variant=minbase",
419- "--include=python-apt,apt-utils,gpgv,ubuntu-keyring,ca-certificates",
420- DISTRO,
421- target,
422- MIRROR])
423+ subprocess.call(
424+ ["debootstrap",
425+ "--arch=%s" % ARCH,
426+ # smaller version of the minimal system
427+ "--variant=minbase",
428+ "--include=python-apt,apt-utils,gpgv,ubuntu-keyring,"
429+ "ca-certificates",
430+ DISTRO,
431+ target,
432+ MIRROR])
433 subprocess.call(["chroot", target, "apt-get", "clean"])
434 subprocess.call(["tar", "czf", tarball, target])
435
436@@ -73,7 +78,7 @@
437 subprocess.call(["tar", "xzf", tarball])
438
439 def test_normal_upgrade(self):
440- print "Running normal unattended upgrade in chroot"
441+ print("Running normal unattended upgrade in chroot")
442 options = MockOptions()
443 options.minimal_upgrade_steps = False
444 # run it
445@@ -82,7 +87,7 @@
446 self.assertTrue(self._verify_install_log_in_real_chroot(target))
447
448 def test_minimal_steps_upgrade(self):
449- print "Running minimal steps unattended upgrade in chroot"
450+ print("Running minimal steps unattended upgrade in chroot")
451 options = MockOptions()
452 options.minimal_upgrade_steps = True
453 # run it
454@@ -91,14 +96,15 @@
455 self.assertTrue(self._verify_install_log_in_real_chroot(target))
456
457 def test_upgrade_on_shutdown_upgrade(self):
458- print "Running unattended upgrade on shutdown (download and install) in chroot"
459+ print("Running unattended upgrade on shutdown (download and install) "
460+ "in chroot")
461 # ensure that it actually installs in shutdown env mode
462 options = MockOptions()
463 os.environ["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
464 apt.apt_pkg.config.set("Unattended-Upgrade::InstallOnShutdown", "1")
465 target = self._run_upgrade_test_in_real_chroot(options)
466 self.assertTrue(self._verify_install_log_in_real_chroot(target))
467-
468+
469 def _get_lockfile_location(self, target):
470 return os.path.join(
471 target, "var/log/unattended-upgrades/unattended-upgrades.log")
472@@ -114,14 +120,13 @@
473 open(os.path.join(target, "etc/apt/apt.conf"), "w").write(APT_CONF)
474 open(os.path.join(target, "etc/apt/sources.list"), "w").write(
475 SOURCES_LIST)
476-
477
478 def _run_upgrade_test_in_real_chroot(self, options, clean_chroot=True):
479 """ helper that runs the unattended-upgrade in a chroot
480 and does some basic verifications
481 """
482 if os.getuid() != 0:
483- print "Skipping because uid != 0"
484+ print("Skipping because uid != 0")
485 return
486
487 # clear to avoid pollution in the chroot
488@@ -130,7 +135,7 @@
489 # create chroot
490 target = "./test-chroot.%s" % DISTRO
491
492- # setup chroot if needed
493+ # setup chroot if needed
494 if clean_chroot:
495 self._setup_chroot(target)
496
497@@ -143,7 +148,7 @@
498 if not os.path.exists("/var/log/unattended-upgrades/"):
499 os.makedirs("/var/log/unattended-upgrades/")
500 # make sure we are up-to-date
501- subprocess.call(["apt-get","update", "-q", "-q"])
502+ subprocess.call(["apt-get", "update", "-q", "-q"])
503 # run it
504 apt.apt_pkg.config.clear("Unattended-Upgrade::Allowed-Origins")
505 apt.apt_pkg.config.clear("Unattended-Upgrade::Origins-Pattern")
506@@ -153,7 +158,7 @@
507 unattended_upgrade.main(options)
508 os._exit(0)
509 else:
510- has_progress=False
511+ has_progress = False
512 all_progress = ""
513 last_progress = ""
514 progress_log = os.path.join(
515@@ -171,9 +176,9 @@
516 if pid == apid:
517 ret = os.WEXITSTATUS(status)
518 break
519- #print "*******************", all_progress
520+ #print("*******************", all_progress)
521 self.assertEqual(ret, 0)
522- # this number is a bit random, we just want to be sure we have
523+ # this number is a bit random, we just want to be sure we have
524 # progress data
525 self.assertTrue(has_progress, True)
526 self.assertTrue(len(all_progress) > 5)
527@@ -183,11 +188,12 @@
528 # examine log
529 log = self._get_lockfile_location(target)
530 logfile = open(log).read()
531- #print logfile
532- NEEDLE_PKG="ca-certificates"
533+ #print(logfile)
534+ NEEDLE_PKG = "ca-certificates"
535 if not re.search(
536 "Packages that are upgraded:.*%s" % NEEDLE_PKG, logfile):
537- logging.warn("Can not find expected %s upgrade in log" % NEEDLE_PKG)
538+ logging.warn("Can not find expected %s upgrade in log" %
539+ NEEDLE_PKG)
540 return False
541 if "ERROR Installing the upgrades failed" in logfile:
542 logging.warn("Got a ERROR in the logfile")
543@@ -196,9 +202,10 @@
544 target, "var/log/unattended-upgrades/*-dpkg*.log")
545 dpkg_logfile = open(glob.glob(dpkg_log)[0]).read()
546 if not "Preparing to replace %s" % NEEDLE_PKG in dpkg_logfile:
547- logging.warn("Did not find %s upgrade in the dpkg.log" % NEEDLE_PKG)
548+ logging.warn("Did not find %s upgrade in the dpkg.log" %
549+ NEEDLE_PKG)
550 return False
551- #print dpkg_logfile
552+ #print(dpkg_logfile)
553 return True
554
555
556
557=== modified file 'test/test_logdir.py'
558--- test/test_logdir.py 2012-06-29 07:08:35 +0000
559+++ test/test_logdir.py 2012-10-05 14:59:30 +0000
560@@ -1,9 +1,8 @@
561-#!/usr/bin/python
562+#!/usr/bin/python3
563
564 import apt_pkg
565 import logging
566 import os
567-import mock
568 import sys
569 import tempfile
570 import unittest
571@@ -11,10 +10,12 @@
572 sys.path.insert(0, "..")
573 from unattended_upgrade import _setup_logging
574
575+
576 class MockOptions:
577 dry_run = False
578 debug = False
579
580+
581 class TestLogdir(unittest.TestCase):
582
583 def setUp(self):
584
585=== modified file 'test/test_mail.py'
586--- test/test_mail.py 2012-07-13 12:20:03 +0000
587+++ test/test_mail.py 2012-10-05 14:59:30 +0000
588@@ -1,11 +1,14 @@
589-#!/usr/bin/python
590+#!/usr/bin/python3
591 # -*- coding: utf-8 -*-
592+from __future__ import unicode_literals
593+
594 import apt_pkg
595 import os
596+import sys
597 import unittest
598
599+from io import StringIO
600 from email.parser import Parser
601-from StringIO import StringIO
602
603 import unattended_upgrade
604 from unattended_upgrade import send_summary_mail, setup_apt_listchanges
605@@ -40,9 +43,10 @@
606 res = successful
607 pkgs_kept_back = []
608 # include some unicode chars here for good measure
609- mem_log = StringIO(u"mem_log text üöä")
610+ mem_log = StringIO("mem_log text üöä")
611 logfile_dpkg = "./apt-term.log"
612- open("./apt-term.log", "w").write("logfile_dpkg text")
613+ with open("./apt-term.log", "w") as fp:
614+ fp.write("logfile_dpkg text")
615 return (pkgs, res, pkgs_kept_back, mem_log, logfile_dpkg)
616
617 def _verify_common_mail_content(self, mail_txt):
618@@ -50,47 +54,55 @@
619 self.assertTrue(expected_string in mail_txt)
620
621 def test_summary_mail_reboot(self):
622- open("./reboot-required","w").write("")
623+ with open("./reboot-required", "w") as fp:
624+ fp.write("")
625 send_summary_mail(*self._return_mock_data())
626 os.unlink("./reboot-required")
627- mail_txt = open("mail.txt").read()
628+ # this is used for py2 compat for py3 only we can do
629+ # remove the "rb" and the subsequent '.decode("utf-8")'
630+ with open("mail.txt", "rb") as fp:
631+ mail_txt = fp.read().decode("utf-8")
632 self.assertTrue("[reboot required]" in mail_txt)
633 self._verify_common_mail_content(mail_txt)
634-
635+
636 def test_summary_mail_no_reboot(self):
637 send_summary_mail(*self._return_mock_data())
638- mail_txt = open("mail.txt").read()
639+ with open("mail.txt", "rb") as fp:
640+ mail_txt = fp.read().decode("utf-8")
641 self.assertFalse("[reboot required]" in mail_txt)
642 self._verify_common_mail_content(mail_txt)
643-
644+
645 def test_summary_mail_only_on_error(self):
646 # default is to always send mail, ensure this is correct
647 # for both success and failure
648 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "false")
649 send_summary_mail(*self._return_mock_data(successful=True))
650- self._verify_common_mail_content(open("mail.txt").read())
651+ with open("mail.txt", "rb") as fp:
652+ self._verify_common_mail_content(fp.read().decode("utf-8"))
653 os.remove("mail.txt")
654 # now with a simulated failure
655 send_summary_mail(*self._return_mock_data(successful=False))
656- self._verify_common_mail_content(open("mail.txt").read())
657+ with open("mail.txt", "rb") as fp:
658+ self._verify_common_mail_content(fp.read().decode("utf-8"))
659 os.remove("mail.txt")
660 # now test with "MailOnlyOnError"
661 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "true")
662 send_summary_mail(*self._return_mock_data(successful=True))
663 self.assertFalse(os.path.exists("mail.txt"))
664 send_summary_mail(*self._return_mock_data(successful=False))
665- mail_txt = open("mail.txt").read()
666+ with open("mail.txt", "rb") as fp:
667+ mail_txt = fp.read().decode("utf-8")
668 self._verify_common_mail_content(mail_txt)
669 self.assertTrue("Unattended upgrade returned: False" in mail_txt)
670 self.assertTrue(os.path.exists("mail.txt"))
671
672 def test_apt_listchanges(self):
673 # test with sendmail available
674- unattended_upgrade.SENDMAIL_BINARY="/bin/true"
675+ unattended_upgrade.SENDMAIL_BINARY = "/bin/true"
676 setup_apt_listchanges("./data/listchanges.conf.mail")
677 self.assertEqual(os.environ["APT_LISTCHANGES_FRONTEND"], "mail")
678 # test without sendmail
679- unattended_upgrade.SENDMAIL_BINARY="/bin/not-here-xxxxxxxxx"
680+ unattended_upgrade.SENDMAIL_BINARY = "/bin/not-here-xxxxxxxxx"
681 setup_apt_listchanges("./data/listchanges.conf.pager")
682 self.assertEqual(os.environ["APT_LISTCHANGES_FRONTEND"], "none")
683
684@@ -108,6 +120,7 @@
685 # we don't accidently try
686 self.assertFalse('text/plain; charset="utf-8"' in mail_txt)
687
688+
689 class SendmailTestCase(CommonTestsForMailxAndSendmail, unittest.TestCase):
690
691 def setUp(self):
692@@ -117,10 +130,15 @@
693 def _verify_common_mail_content(self, mail_txt):
694 CommonTestsForMailxAndSendmail._verify_common_mail_content(
695 self, mail_txt)
696+
697+ # python2 needs this as utf8 encoded string (not unicode)
698+ if sys.version < '3':
699+ mail_txt = mail_txt.encode("utf-8")
700+
701 msg = Parser().parsestr(mail_txt)
702 content_type = msg["Content-Type"]
703 self.assertEqual(content_type, 'text/plain; charset="utf-8"')
704-
705+
706
707 class SendmailAndMailxTestCase(SendmailTestCase):
708
709@@ -132,4 +150,3 @@
710 if __name__ == "__main__":
711 #logging.basicConfig(level=logging.DEBUG)
712 unittest.main()
713-
714
715=== modified file 'test/test_minimal_partitions.py'
716--- test/test_minimal_partitions.py 2011-11-18 10:46:15 +0000
717+++ test/test_minimal_partitions.py 2012-10-05 14:59:30 +0000
718@@ -1,33 +1,32 @@
719-#!/usr/bin/python
720+#!/usr/bin/python3
721
722 import apt
723 import apt_pkg
724 import os
725-import logging
726 import unittest
727-import sys
728-import time
729
730 import unattended_upgrade
731
732+
733 class LogInstallProgressMock(unattended_upgrade.LogInstallProgress):
734
735 # klass data so that we can veriy in the test as the actual
736 # object is destroyed
737 DATA = []
738-
739+
740 # overwrite to log the data
741 def status_change(self, pkg, percent, status):
742- print pkg, percent
743+ print(pkg, percent)
744 self.DATA.append([pkg, percent])
745
746+
747 class TestMinimalPartitions(unittest.TestCase):
748
749 def setUp(self):
750 # setup dry-run mode for apt
751 apt_pkg.config.set("Dir::Cache", "/tmp")
752- apt_pkg.config.set("Debug::NoLocking","1")
753- apt_pkg.config.set("Debug::pkgDPkgPM","1")
754+ apt_pkg.config.set("Debug::NoLocking", "1")
755+ apt_pkg.config.set("Debug::pkgDPkgPM", "1")
756 apt_pkg.config.set("Dir::State::extended_states", "./extended_states")
757 apt_pkg.config.clear("Dpkg::Post-Invoke")
758 apt_pkg.config.clear("Dpkg::Pre-Install-Pkgs")
759@@ -40,7 +39,8 @@
760 def test_upgrade_in_minimal_steps(self):
761 self.cache.upgrade(True)
762 pkgs_to_upgrade = [pkg.name for pkg in self.cache.get_changes()]
763- unattended_upgrade.PROGRESS_LOG="./aptroot/var/run/unatteded-upgrades.progress"
764+ unattended_upgrade.PROGRESS_LOG = \
765+ "./aptroot/var/run/unatteded-upgrades.progress"
766 unattended_upgrade.LogInstallProgress = LogInstallProgressMock
767 unattended_upgrade.upgrade_in_minimal_steps(
768 self.cache, pkgs_to_upgrade)
769
770=== modified file 'test/test_origin_pattern.py'
771--- test/test_origin_pattern.py 2012-08-14 11:55:21 +0000
772+++ test/test_origin_pattern.py 2012-10-05 14:59:30 +0000
773@@ -1,4 +1,4 @@
774-#!/usr/bin/python
775+#!/usr/bin/python3
776
777 import apt_pkg
778 import logging
779@@ -12,49 +12,63 @@
780 UnknownMatcherError,
781 )
782
783+
784 class MockOrigin():
785 pass
786+
787+
788 class MockCandidate():
789 pass
790+
791+
792 class MockPackage():
793 pass
794+
795+
796 class MockCache(list):
797 pass
798+
799+
800 class MockDepCache():
801 pass
802
803+
804 class TestOriginPatern(unittest.TestCase):
805
806 def setUp(self):
807 pass
808+
809 def tearDown(self):
810 pass
811+
812 def test_match_whitelist_string(self):
813 origin = self._get_mock_origin(
814 "OriginUbuntu", "LabelUbuntu", "ArchiveUbuntu",
815 "archive.ubuntu.com", "main")
816 # good
817- s="o=OriginUbuntu"
818+ s = "o=OriginUbuntu"
819 self.assertTrue(match_whitelist_string(s, origin))
820- s="o=OriginUbuntu,l=LabelUbuntu,a=ArchiveUbuntu,site=archive.ubuntu.com"
821+ s = "o=OriginUbuntu,l=LabelUbuntu,a=ArchiveUbuntu," \
822+ "site=archive.ubuntu.com"
823 self.assertTrue(match_whitelist_string(s, origin))
824 # bad
825- s=""
826- self.assertFalse(match_whitelist_string(s, origin))
827- s="o=something"
828- self.assertFalse(match_whitelist_string(s, origin))
829- s="o=LabelUbuntu,a=no-match"
830+ s = ""
831+ self.assertFalse(match_whitelist_string(s, origin))
832+ s = "o=something"
833+ self.assertFalse(match_whitelist_string(s, origin))
834+ s = "o=LabelUbuntu,a=no-match"
835 self.assertFalse(match_whitelist_string(s, origin))
836 # with escaping
837 origin = self._get_mock_origin("Google, Inc.", archive="stable")
838 # good
839- s="o=Google\, Inc.,a=stable"
840+ s = "o=Google\, Inc.,a=stable"
841 self.assertTrue(match_whitelist_string(s, origin))
842
843 def test_match_whitelist_from_conffile(self):
844 # read some
845 apt_pkg.config.clear("Unattended-Upgrade")
846- apt_pkg.read_config_file(apt_pkg.config, "./data/50unattended-upgrades.Test")
847+ apt_pkg.read_config_file(
848+ apt_pkg.config, "./data/50unattended-upgrades.Test")
849 allowed_origins = unattended_upgrade.get_allowed_origins()
850 #print allowed_origins
851 self.assertTrue("o=aOrigin,a=aArchive" in allowed_origins)
852@@ -63,7 +77,8 @@
853
854 def test_compatiblity(self):
855 apt_pkg.config.clear("Unattended-Upgrade")
856- apt_pkg.read_config_file(apt_pkg.config, "./data/50unattended-upgrades.compat")
857+ apt_pkg.read_config_file(
858+ apt_pkg.config, "./data/50unattended-upgrades.compat")
859 allowed_origins = unattended_upgrade.get_allowed_origins()
860 #print allowed_origins
861 self.assertTrue("o=Google\, Inc.,a=stable" in allowed_origins)
862@@ -74,7 +89,7 @@
863
864 def test_unkown_matcher(self):
865 apt_pkg.config.clear("Unattended-Upgrade")
866- s="xxx=OriginUbuntu"
867+ s = "xxx=OriginUbuntu"
868 with self.assertRaises(UnknownMatcherError):
869 self.assertTrue(match_whitelist_string(s, None))
870
871@@ -90,10 +105,12 @@
872 allowed_origins = ["o=Ubuntu"]
873 blacklist = ["linux-.*"]
874 # with blacklist pkg
875- self.assertFalse(check_changes_for_sanity(cache, allowed_origins, blacklist))
876+ self.assertFalse(
877+ check_changes_for_sanity(cache, allowed_origins, blacklist))
878 # with "normal" pkg
879 pkg.name = "apt"
880- self.assertTrue(check_changes_for_sanity(cache, allowed_origins, blacklist))
881+ self.assertTrue(
882+ check_changes_for_sanity(cache, allowed_origins, blacklist))
883
884 def _get_mock_origin(self, aorigin="", label="", archive="",
885 site="", component=""):
886@@ -125,4 +142,3 @@
887 if __name__ == "__main__":
888 logging.basicConfig(level=logging.DEBUG)
889 unittest.main()
890-
891
892=== added file 'test/test_pep8.py'
893--- test/test_pep8.py 1970-01-01 00:00:00 +0000
894+++ test/test_pep8.py 2012-10-05 14:59:30 +0000
895@@ -0,0 +1,17 @@
896+import glob
897+import os
898+import subprocess
899+import unittest
900+
901+
902+class PackagePep8TestCase(unittest.TestCase):
903+
904+ def test_all_code(self):
905+ res = 0
906+ py_files = glob.glob(os.path.join(os.path.dirname(__file__), "*.py"))
907+ res += subprocess.call(["pep8", "--repeat", ] + py_files)
908+ self.assertEqual(res, 0)
909+
910+
911+if __name__ == "__main__":
912+ unittest.main()
913
914=== modified file 'test/test_pyflakes.py'
915--- test/test_pyflakes.py 2012-07-13 16:40:10 +0000
916+++ test/test_pyflakes.py 2012-10-05 14:59:30 +0000
917@@ -2,12 +2,14 @@
918 import subprocess
919 import unittest
920
921+
922 class TestPyflakesClean(unittest.TestCase):
923 """ ensure that the tree is pyflakes clean """
924
925 def test_pyflakes_clean(self):
926- target = os.path.join(os.path.dirname(__file__), "..", "unattended-upgrade")
927- self.assertEqual(subprocess.call(["pyflakes", target]), 0)
928+ path = os.path.join(
929+ os.path.dirname(__file__), "unattended_upgrade.py")
930+ self.assertEqual(subprocess.call(["pyflakes", path]), 0)
931
932
933 if __name__ == "__main__":
934
935=== modified file 'test/test_substitute.py'
936--- test/test_substitute.py 2011-02-04 11:05:12 +0000
937+++ test/test_substitute.py 2012-10-05 14:59:30 +0000
938@@ -1,17 +1,13 @@
939-#!/usr/bin/python
940+#!/usr/bin/python3
941
942-import apt
943 import apt_pkg
944-import os
945 import logging
946 import unittest
947-import sys
948-
949-from StringIO import StringIO
950
951 import unattended_upgrade
952 from unattended_upgrade import substitute, get_allowed_origins
953
954+
955 class TestSubstitude(unittest.TestCase):
956
957 def setUp(self):
958@@ -36,4 +32,3 @@
959 if __name__ == "__main__":
960 logging.basicConfig(level=logging.DEBUG)
961 unittest.main()
962-
963
964=== modified file 'unattended-upgrade'
965--- unattended-upgrade 2012-08-14 11:55:21 +0000
966+++ unattended-upgrade 2012-10-05 14:59:30 +0000
967@@ -1,4 +1,4 @@
968-#!/usr/bin/python
969+#!/usr/bin/python3
970 # Copyright (c) 2005-2012 Canonical Ltd
971 #
972 # AUTHOR:
973@@ -20,26 +20,27 @@
974 # along with unattended-upgrades; if not, write to the Free Software
975 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
976 #
977-
978 import apt_inst
979 import apt_pkg
980
981 import copy
982 import datetime
983-import email.Charset
984+import email.charset
985 import fcntl
986 import re
987 import os
988 import string
989 import sys
990
991-from email.Message import Message
992+from io import StringIO
993+from email.message import Message
994 from optparse import OptionParser
995-from StringIO import StringIO
996-from subprocess import Popen, PIPE
997-
998-import warnings
999-warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning)
1000+
1001+from subprocess import (
1002+ Popen,
1003+ PIPE,
1004+ )
1005+
1006 import apt
1007 import logging
1008 import lsb_release
1009@@ -57,29 +58,32 @@
1010 DISTRO_ID = lsb_release.get_distro_information()['ID']
1011
1012 # progress information is written here
1013-PROGRESS_LOG="/var/run/unattended-upgrades.progress"
1014+PROGRESS_LOG = "/var/run/unattended-upgrades.progress"
1015
1016 # set from the sigint signal handler
1017-SIGNAL_STOP_REQUEST=False
1018+SIGNAL_STOP_REQUEST = False
1019+
1020
1021 class UnknownMatcherError(ValueError):
1022 pass
1023
1024
1025 class UnattendedUpgradesCache(apt.Cache):
1026-
1027+
1028 def __init__(self, rootdir, allowed_origins):
1029 apt.Cache.__init__(self, rootdir=rootdir)
1030 self.allowed_origins = allowed_origins
1031- # ensure we update the candidate versions
1032+ # ensure we update the candidate versions
1033 self.adjust_candidate_versions()
1034+
1035 def clear(self):
1036 apt.Cache.clear(self)
1037- # ensure we update the candidate versions
1038+ # ensure we update the candidate versions
1039 self.adjust_candidate_versions()
1040+
1041 def adjust_candidate_versions(self):
1042 """ Adjust candidate versions to match highest allowed origin
1043-
1044+
1045 This adjusts the origin even if the candidate has a higher
1046 version
1047 """
1048@@ -114,20 +118,19 @@
1049 (/var/run/unattended-upgrades.progress by default)
1050 """
1051
1052- LOG = PROGRESS_LOG
1053+ LOG = PROGRESS_LOG
1054
1055 def status_change(self, pkg, percent, status):
1056- f=open(self.LOG, "w")
1057- f.write(_("Progress: %s %% (%s)") % (percent, pkg))
1058- f.close()
1059+ with open(self.LOG, "w") as f:
1060+ f.write(_("Progress: %s %% (%s)") % (percent, pkg))
1061
1062 def _fixup_fds(self):
1063- required_fds = [ 0, 1, 2, # stdin, stdout, stderr
1064- self.writefd,
1065- self.write_stream.fileno(),
1066- self.statusfd,
1067- self.status_stream.fileno()
1068- ]
1069+ required_fds = [0, 1, 2, # stdin, stdout, stderr
1070+ self.writefd,
1071+ self.write_stream.fileno(),
1072+ self.statusfd,
1073+ self.status_stream.fileno()
1074+ ]
1075 # ensure that our required fds close on exec
1076 for fd in required_fds[3:]:
1077 old_flags = fcntl.fcntl(fd, fcntl.F_GETFD)
1078@@ -140,19 +143,19 @@
1079 try:
1080 fd = int(fdname)
1081 except Exception as e:
1082- print "ERROR: can not get fd for '%s'" % fdname
1083+ print("ERROR: can not get fd for '%s'" % fdname)
1084 if fd in required_fds:
1085 continue
1086 try:
1087 os.close(fd)
1088- #print "closed: ", fd
1089+ #print("closed: ", fd)
1090 except OSError as e:
1091 # there will be one fd that can not be closed
1092 # as its the fd from pythons internal diropen()
1093 # so its ok to ignore one close error
1094 error_count += 1
1095 if error_count > 1:
1096- print "ERROR: os.close(%s): %s" % (fd, e)
1097+ print("ERROR: os.close(%s): %s" % (fd, e))
1098
1099 def fork(self):
1100 pid = os.fork()
1101@@ -162,53 +165,62 @@
1102
1103
1104 class Unlocked:
1105- """ context manager for unlocking the apt lock while cache.commit()
1106- is run
1107- """
1108+ """
1109+ Context manager for unlocking the apt lock while cache.commit() is run
1110+ """
1111+
1112 def __enter__(self):
1113 try:
1114 apt_pkg.pkgsystem_unlock()
1115 except:
1116 pass
1117+
1118 def __exit__(self, exc_type, exc_value, exc_tb):
1119 try:
1120 apt_pkg.pkgsystem_unlock()
1121 except:
1122 pass
1123
1124+
1125 def is_dpkg_journal_dirty():
1126 """
1127- test if the dpkg journal is dirty
1128+ Return True if the dpkg journal is dirty
1129 (similar to debSystem::CheckUpdates)
1130 """
1131- d = os.path.dirname(
1132- apt_pkg.config.find_file("Dir::State::status"))+"/updates"
1133+ d = os.path.join(
1134+ os.path.dirname(apt_pkg.config.find_file("Dir::State::status")),
1135+ "updates")
1136 for f in os.listdir(d):
1137 if re.match("[0-9]+", f):
1138 return True
1139 return False
1140
1141+
1142 def signal_handler(signal, frame):
1143 logging.warn("SIGUSR1 recieved, will stop")
1144 global SIGNAL_STOP_REQUEST
1145- SIGNAL_STOP_REQUEST=True
1146+ SIGNAL_STOP_REQUEST = True
1147+
1148
1149 def substitute(line):
1150- """ substitude known mappings and return a new string
1151+ """ substitude known mappings and return a new string
1152
1153 Currently supported ${distro-release}
1154 """
1155- mapping = {"distro_codename" : get_distro_codename(),
1156- "distro_id" : get_distro_id(),
1157+ mapping = {"distro_codename": get_distro_codename(),
1158+ "distro_id": get_distro_id(),
1159 }
1160 return string.Template(line).substitute(mapping)
1161-
1162+
1163+
1164 def get_distro_codename():
1165 return DISTRO_CODENAME
1166
1167+
1168 def get_distro_id():
1169 return DISTRO_ID
1170
1171+
1172 def get_allowed_origins_legacy():
1173 """ legacy support for old Allowed-Origins var """
1174 allowed_origins = []
1175@@ -222,10 +234,11 @@
1176 distro_id = re.sub(r'([^\\]),', r'\1\\,', distro_id)
1177 distro_codename = re.sub(r'([^\\]),', r'\1\\,', distro_codename)
1178 # convert to new format
1179- allowed_origins.append("o=%s,a=%s" % (substitute(distro_id),
1180+ allowed_origins.append("o=%s,a=%s" % (substitute(distro_id),
1181 substitute(distro_codename)))
1182 return allowed_origins
1183
1184+
1185 def get_allowed_origins():
1186 """ return a list of allowed origins from apt.conf
1187
1188@@ -236,6 +249,7 @@
1189 allowed_origins.append(substitute(s))
1190 return allowed_origins
1191
1192+
1193 def match_whitelist_string(whitelist, origin):
1194 """
1195 take a whitelist string in the form "origin=Debian,label=Debian-Security"
1196@@ -251,9 +265,10 @@
1197 whitelist = whitelist.replace("\,", "%2C")
1198 for token in whitelist.split(","):
1199 # strip and unquote the "," back
1200- (what, value) = [s.strip().replace("%2C",",")
1201+ (what, value) = [s.strip().replace("%2C", ",")
1202 for s in token.split("=")]
1203- #logging.debug("matching '%s'='%s' against '%s'" % (what, value, origin))
1204+ #logging.debug("matching '%s'='%s' against '%s'" % (
1205+ # what, value, origin))
1206 # first char is apt-cache policy output, send is the name
1207 # in the Release file
1208 if what in ("o", "origin"):
1209@@ -272,6 +287,7 @@
1210 what, token))
1211 return res
1212
1213+
1214 def upgrade_normal(cache, pkgs_to_upgrade, logfile_dpkg):
1215 error = None
1216 res = False
1217@@ -279,17 +295,18 @@
1218 try:
1219 with Unlocked():
1220 res = cache.commit(install_progress=iprogress)
1221- except SystemError,e:
1222+ except SystemError as e:
1223 error = e
1224 if res:
1225 logging.info(_("All upgrades installed"))
1226 else:
1227 logging.error(_("Installing the upgrades failed!"))
1228 logging.error(_("error message: '%s'") % error)
1229- logging.error(_("dpkg returned a error! See '%s' for details") % \
1230+ logging.error(_("dpkg returned a error! See '%s' for details") %
1231 logfile_dpkg)
1232 return res
1233
1234+
1235 def upgrade_in_minimal_steps(cache, pkgs_to_upgrade, logfile_dpkg=""):
1236
1237 install_log = LogInstallProgress()
1238@@ -320,13 +337,15 @@
1239 smallest_partition = changes
1240 break
1241 if len(changes) < len(smallest_partition):
1242- logging.debug("found partition of size %s (%s)" % (len(changes), changes))
1243+ logging.debug("found partition of size %s (%s)" % (
1244+ len(changes), changes))
1245 smallest_partition = changes
1246 cache.clear()
1247
1248 # write progress log information
1249 if len(pkgs_to_upgrade) > 0:
1250- percent = (len(pkgs_to_upgrade)-len(to_upgrade)) / float(len(pkgs_to_upgrade))*100.0
1251+ percent = ((len(pkgs_to_upgrade) - len(to_upgrade)) /
1252+ float(len(pkgs_to_upgrade)) * 100.0)
1253 else:
1254 percent = 100.0
1255 install_log.status_change(pkg=",".join(smallest_partition),
1256@@ -343,19 +362,20 @@
1257 if not res:
1258 raise Exception("cache.commit() returned false")
1259 cache.open()
1260- except Exception, e:
1261+ except Exception as e:
1262 logging.error(_("Installing the upgrades failed!"))
1263 logging.error(_("error message: '%s'") % e)
1264- logging.error(_("dpkg returned a error! See '%s' for details") % \
1265+ logging.error(_("dpkg returned a error! See '%s' for details") %
1266 logfile_dpkg)
1267 return False
1268- to_upgrade = to_upgrade-set(smallest_partition)
1269+ to_upgrade = to_upgrade - set(smallest_partition)
1270 logging.debug("left to upgrade %s" % to_upgrade)
1271 if len(to_upgrade) == 0:
1272 logging.info(_("All upgrades installed"))
1273 break
1274 return True
1275
1276+
1277 def is_allowed_origin(ver, allowed_origins):
1278 if not ver:
1279 return False
1280@@ -365,6 +385,7 @@
1281 return True
1282 return False
1283
1284+
1285 def is_pkgname_in_blacklist(pkgname, blacklist):
1286 for blacklist_regexp in blacklist:
1287 if re.match(blacklist_regexp, pkgname):
1288@@ -372,6 +393,7 @@
1289 return True
1290 return False
1291
1292+
1293 def check_changes_for_sanity(cache, allowed_origins, blacklist):
1294 if cache._depcache.broken_count != 0:
1295 return False
1296@@ -392,33 +414,39 @@
1297 ignore_require_restart = apt_pkg.config.find_b(
1298 "Unattended-Upgrade::IgnoreAppsRequireRestart", False)
1299 if (pkg.marked_upgrade and
1300- ignore_require_restart == False and
1301+ ignore_require_restart is False and
1302 pkg.candidate.record.get("Upgrade-Requires") == "app-restart"):
1303- logging.debug("pkg '%s' requires app-restart, not safe to upgrade unattended")
1304+ logging.debug("pkg '%s' requires app-restart, not safe to "
1305+ "upgrade unattended")
1306 return False
1307 return True
1308
1309+
1310 def pkgname_from_deb(debfile):
1311 # FIXME: add error checking here
1312 try:
1313 control = apt_inst.DebFile(debfile).control.extractdata("control")
1314 sections = apt_pkg.TagSection(control)
1315 return sections["Package"]
1316- except (IOError, SystemError), e:
1317+ except (IOError, SystemError) as e:
1318 logging.error("failed to read deb file '%s' (%s)" % (debfile, e))
1319 # dumb fallback
1320 return debfile.split("_")[0]
1321
1322+
1323 def get_md5sum_for_file_in_deb(deb_file, conf_file):
1324- dpkg_cmd = ["dpkg-deb","--fsys-tarfile", deb_file]
1325- tar_cmd = ["tar","-x","-O", "-f","-", "."+conf_file]
1326+ dpkg_cmd = ["dpkg-deb", "--fsys-tarfile", deb_file]
1327+ tar_cmd = ["tar", "-x", "-O", "-f", "-", "." + conf_file]
1328 md5_cmd = ["md5sum"]
1329 dpkg_p = Popen(dpkg_cmd, stdout=PIPE)
1330- tar_p = Popen(tar_cmd, stdin=dpkg_p.stdout, stdout=PIPE)
1331- md5_p = Popen(md5_cmd, stdin=tar_p.stdout, stdout=PIPE)
1332+ tar_p = Popen(tar_cmd, stdin=dpkg_p.stdout, stdout=PIPE,
1333+ universal_newlines=True)
1334+ md5_p = Popen(md5_cmd, stdin=tar_p.stdout, stdout=PIPE,
1335+ universal_newlines=True)
1336 pkg_md5sum = md5_p.communicate()[0].split()[0]
1337 return pkg_md5sum
1338
1339+
1340 # prefix is *only* needed for the build-in tests
1341 def conffile_prompt(destFile, prefix=""):
1342 logging.debug("check_conffile_prompt('%s')" % destFile)
1343@@ -426,7 +454,7 @@
1344
1345 # get the conffiles for the /var/lib/dpkg/status file
1346 status_file = apt_pkg.config.find("Dir::State::status")
1347- tagfile = apt_pkg.TagFile(open(status_file,"r"))
1348+ tagfile = apt_pkg.TagFile(open(status_file, "r"))
1349 conffiles = ""
1350 for section in tagfile:
1351 if section.get("Package") == pkgname:
1352@@ -440,21 +468,22 @@
1353 pkg_conffiles = ""
1354 deb = apt_inst.DebFile(destFile)
1355 try:
1356- pkg_conffiles = deb.control.extractdata("conffiles").strip()
1357+ pkg_conffiles = deb.control.extractdata("conffiles").strip().decode(
1358+ "utf-8")
1359 except LookupError as e:
1360 logging.debug("No conffiles in deb '%s' (%s)" % (destFile, e))
1361
1362 # Conffiles:
1363 # /etc/bash_completion.d/m-a c7780fab6b14d75ca54e11e992a6c11c
1364 dpkg_status_conffiles = {}
1365- for line in string.split(conffiles,"\n"):
1366+ for line in conffiles.splitlines():
1367 # ignore empty lines
1368- line = string.strip(line)
1369+ line = line.strip()
1370 if not line:
1371 continue
1372 # show what we do
1373 logging.debug("conffile line: '%s'", line)
1374- l = string.split(line)
1375+ l = line.split()
1376 conf_file = l[0]
1377 md5 = l[1]
1378 if len(l) > 2:
1379@@ -462,13 +491,13 @@
1380 else:
1381 obs = None
1382 # ignore if conffile is obsolete or does not exist
1383- if obs == "obsolete" or not os.path.exists(prefix+conf_file):
1384+ if obs == "obsolete" or not os.path.exists(prefix + conf_file):
1385 continue
1386 # ignore state "newconffile" until its clearer if there
1387 # might be a dpkg prompt (LP: #936870)
1388 if md5 == "newconffile":
1389 continue
1390- if (not pkg_conffiles or
1391+ if (not pkg_conffiles or
1392 not conf_file in pkg_conffiles.split("\n")):
1393 logging.debug("'%s' not in package conffiles '%s'" % (
1394 conf_file, pkg_conffiles))
1395@@ -476,7 +505,8 @@
1396 # record for later
1397 dpkg_status_conffiles[conf_file] = md5
1398 # test against the installed file
1399- current_md5 = apt_pkg.md5sum(open(prefix+conf_file).read())
1400+ with open(prefix + conf_file, 'rb') as fb:
1401+ current_md5 = apt_pkg.md5sum(fb)
1402 logging.debug("current md5: %s" % current_md5)
1403 # hashes are the same, no conffile prompt
1404 if current_md5 == md5:
1405@@ -484,7 +514,7 @@
1406 # calculate md5sum from the deb (may take a bit)
1407 pkg_md5sum = get_md5sum_for_file_in_deb(destFile, conf_file)
1408 logging.debug("pkg_md5sum: %s" % pkg_md5sum)
1409- # the md5sum in the deb is unchanged, this will not
1410+ # the md5sum in the deb is unchanged, this will not
1411 # trigger a conffile prompt
1412 if pkg_md5sum == md5:
1413 continue
1414@@ -493,18 +523,19 @@
1415 # and that will trigger a conffile prompt, we can
1416 # stop processing at this point and just return True
1417 return True
1418-
1419+
1420 # now check if there are conffiles in the pkg that where not there
1421 # in the previous version in the dpkg status file
1422 if pkg_conffiles:
1423 for conf_file in pkg_conffiles.split("\n"):
1424 if (not conf_file in dpkg_status_conffiles and
1425- os.path.exists(prefix+conf_file)):
1426+ os.path.exists(prefix + conf_file)):
1427 logging.debug("found conffile '%s' in new pkg but on dpkg "
1428 "status" % conf_file)
1429 pkg_md5sum = get_md5sum_for_file_in_deb(destFile, conf_file)
1430- if pkg_md5sum != apt_pkg.md5sum(open(prefix+conf_file).read()):
1431- return True
1432+ with open(prefix + conf_file, 'rb') as fp:
1433+ if pkg_md5sum != apt_pkg.md5sum(fp):
1434+ return True
1435 return False
1436
1437
1438@@ -512,9 +543,9 @@
1439 if not "DPkg::Options" in apt_pkg.config:
1440 return True
1441 options = apt_pkg.config.value_list("DPkg::Options")
1442- for option in map(string.strip, options):
1443- if (option == "--force-confold" or
1444- option == "--force-confnew"):
1445+ for option in options:
1446+ option = option.strip()
1447+ if option in ["--force-confold", "--force-confnew"]:
1448 return False
1449 return True
1450
1451@@ -535,7 +566,7 @@
1452 def wrap(t, width=70, subsequent_indent=""):
1453 out = ""
1454 for s in t.split():
1455- if (len(out)-out.rfind("\n")) + len(s) > width:
1456+ if (len(out) - out.rfind("\n")) + len(s) > width:
1457 out += "\n" + subsequent_indent
1458 out += s + " "
1459 return out
1460@@ -554,8 +585,9 @@
1461
1462
1463 def _send_mail_using_mailx(to_address, subject, body):
1464- mail = subprocess.Popen([
1465- MAIL_BINARY, "-s", subject, to_address], stdin=subprocess.PIPE)
1466+ mail = subprocess.Popen(
1467+ [MAIL_BINARY, "-s", subject, to_address],
1468+ stdin=subprocess.PIPE, universal_newlines=True)
1469 mail.stdin.write(body)
1470 mail.stdin.close()
1471 ret = mail.wait()
1472@@ -565,14 +597,15 @@
1473 def _send_mail_using_sendmail(to_address, subject, body):
1474 # format as a proper mail
1475 msg = Message()
1476- charset = email.Charset.Charset("utf-8")
1477- charset.body_encoding = email.Charset.QP
1478+ charset = email.charset.Charset("utf-8")
1479+ charset.body_encoding = email.charset.QP
1480 msg.set_charset(charset)
1481 msg.set_payload(body)
1482 msg['Subject'] = subject
1483 msg['To'] = to_address
1484 sendmail = subprocess.Popen(
1485- [SENDMAIL_BINARY, "-oi", "-t"], stdin=subprocess.PIPE)
1486+ [SENDMAIL_BINARY, "-oi", "-t"],
1487+ stdin=subprocess.PIPE, universal_newlines=True)
1488 sendmail.stdin.write(msg.as_string())
1489 sendmail.stdin.close()
1490 ret = sendmail.wait()
1491@@ -594,16 +627,18 @@
1492 # mails on on errors, just exit here
1493 if (res and
1494 apt_pkg.config.find_b("Unattended-Upgrade::MailOnlyOnError", False)):
1495- return
1496+ return
1497 # Check if reboot-required flag is present
1498 logging.debug("Sending mail with '%s' to '%s'" % (logfile_dpkg, to_email))
1499 if os.path.isfile(REBOOT_REQUIRED_FILE):
1500- subject = _("[reboot required] unattended-upgrades result for '%s'") % host()
1501+ subject = _(
1502+ "[reboot required] unattended-upgrades result for '%s'") % host()
1503 else:
1504 subject = _("unattended-upgrades result for '%s'") % host()
1505 body = _("Unattended upgrade returned: %s\n\n") % res
1506 if os.path.isfile(REBOOT_REQUIRED_FILE):
1507- body += _("Warning: A reboot is required to complete this upgrade.\n\n")
1508+ body += _(
1509+ "Warning: A reboot is required to complete this upgrade.\n\n")
1510 body += _("Packages that are upgraded:\n")
1511 body += " " + wrap(pkgs, 70, " ")
1512 body += "\n"
1513@@ -613,15 +648,16 @@
1514 body += "\n"
1515 body += "\n"
1516 if os.path.exists(logfile_dpkg):
1517- body += _("Package installation log:")+"\n"
1518- body += open(logfile_dpkg).read()
1519+ body += _("Package installation log:") + "\n"
1520+ with open(logfile_dpkg) as fp:
1521+ body += fp.read()
1522 body += "\n\n"
1523 body += _("Unattended-upgrades log:\n")
1524 body += mem_log.getvalue()
1525
1526- # ensure that the message a utf8 encoded string
1527- if type(body) is unicode:
1528- body= body.encode("utf-8", "replace")
1529+ # python2 needs this as utf8 encoded string (not unicode)
1530+ if sys.version < '3':
1531+ body = body.encode("utf-8")
1532
1533 if os.path.exists(SENDMAIL_BINARY):
1534 ret = _send_mail_using_sendmail(to_email, subject, body)
1535@@ -636,13 +672,13 @@
1536
1537 def do_install(cache, pkgs_to_upgrade, options, logfile_dpkg):
1538 # set debconf to NON_INTERACTIVE, redirect output
1539- os.putenv("DEBIAN_FRONTEND","noninteractive");
1540+ os.putenv("DEBIAN_FRONTEND", "noninteractive")
1541 setup_apt_listchanges()
1542-
1543+
1544 # redirect to log
1545 REDIRECT_INPUT = os.devnull
1546 fd = os.open(REDIRECT_INPUT, os.O_RDWR)
1547- os.dup2(fd,0)
1548+ os.dup2(fd, 0)
1549
1550 logging.info(_("Writing dpkg log to '%s'") % logfile_dpkg)
1551
1552@@ -651,18 +687,21 @@
1553 old_stdout = 1
1554 old_stderr = 2
1555 else:
1556- fd = os.open(logfile_dpkg, os.O_RDWR|os.O_CREAT, 0644)
1557+ fd = os.open(logfile_dpkg, os.O_RDWR | os.O_CREAT, 0o644)
1558 old_stdout = os.dup(1)
1559 old_stderr = os.dup(2)
1560- os.dup2(fd,1)
1561- os.dup2(fd,2)
1562+ os.dup2(fd, 1)
1563+ os.dup2(fd, 2)
1564
1565 try:
1566- if (options.minimal_upgrade_steps or
1567+ if (options.minimal_upgrade_steps or
1568 # COMPAT with the mispelling
1569- apt_pkg.config.find_b("Unattended-Upgrades::MinimalSteps", False) or
1570- apt_pkg.config.find_b("Unattended-Upgrade::MinimalSteps", False)):
1571- open("/var/run/unattended-upgrades.pid", "w").write("%s" % os.getpid())
1572+ apt_pkg.config.find_b(
1573+ "Unattended-Upgrades::MinimalSteps", False) or
1574+ apt_pkg.config.find_b(
1575+ "Unattended-Upgrade::MinimalSteps", False)):
1576+ with open("/var/run/unattended-upgrades.pid", "w") as fp:
1577+ fp.write("%s" % os.getpid())
1578 # try upgrade all "pkgs" in minimal steps
1579 pkg_install_success = upgrade_in_minimal_steps(
1580 cache, [pkg.name for pkg in pkgs_to_upgrade], logfile_dpkg)
1581@@ -685,15 +724,16 @@
1582 apt_pkg.config.clear("Unattended-Upgrade")
1583 # read rootdir (taken from apt.Cache, but we need to run it
1584 # here before the cache gets initialized
1585- if os.path.exists(rootdir+"/etc/apt/apt.conf"):
1586+ if os.path.exists(rootdir + "/etc/apt/apt.conf"):
1587 apt_pkg.read_config_file(apt_pkg.config,
1588 rootdir + "/etc/apt/apt.conf")
1589- if os.path.isdir(rootdir+"/etc/apt/apt.conf.d"):
1590+ if os.path.isdir(rootdir + "/etc/apt/apt.conf.d"):
1591 apt_pkg.read_config_dir(apt_pkg.config,
1592 rootdir + "/etc/apt/apt.conf.d")
1593
1594+
1595 def _get_logdir():
1596- logdir= apt_pkg.config.find_dir(
1597+ logdir = apt_pkg.config.find_dir(
1598 "Unattended-Upgrade::LogDir",
1599 # COMPAT only
1600 apt_pkg.config.find_dir("APT::UnattendedUpgrades::LogDir",
1601@@ -722,7 +762,6 @@
1602 logging.basicConfig(level=logging.INFO,
1603 format='%(asctime)s %(levelname)s %(message)s',
1604 filename=logfile)
1605-
1606 # additional logging
1607 logger = logging.getLogger()
1608 mem_log = StringIO()
1609@@ -734,7 +773,7 @@
1610 mem_log_handler = logging.StreamHandler(mem_log)
1611 logger.addHandler(mem_log_handler)
1612 return mem_log
1613-
1614+
1615
1616 def main(options, rootdir=""):
1617
1618@@ -749,24 +788,28 @@
1619 allowed_origins = get_allowed_origins()
1620
1621 # pkgs that are (for some reason) not save to install
1622- blacklisted_pkgs = apt_pkg.config.value_list("Unattended-Upgrade::Package-Blacklist")
1623- logging.info(_("Initial blacklisted packages: %s"), " ".join(blacklisted_pkgs))
1624+ blacklisted_pkgs = apt_pkg.config.value_list(
1625+ "Unattended-Upgrade::Package-Blacklist")
1626+ logging.info(_("Initial blacklisted packages: %s"),
1627+ " ".join(blacklisted_pkgs))
1628 logging.info(_("Starting unattended upgrades script"))
1629
1630 # display available origin
1631- logging.info(_("Allowed origins are: %s") % map(str,allowed_origins))
1632+ logging.info(_("Allowed origins are: %s") % allowed_origins)
1633
1634 # check if the journal is dirty and if so, take emergceny action
1635 # the alternative is to leave the system potentially unsecure until
1636 # the user comes in and fixes
1637 if (is_dpkg_journal_dirty() and
1638- apt_pkg.config.find_b("Unattended-Upgrade::AutoFixInterruptedDpkg", True)):
1639+ apt_pkg.config.find_b(
1640+ "Unattended-Upgrade::AutoFixInterruptedDpkg", True)):
1641 # ensure the dpkg database is not already locked (LP: #754330)
1642 admindir = os.path.dirname(apt_pkg.config.find("Dir::State::Status"))
1643 lockfd = apt_pkg.get_lock(os.path.join(admindir, "lock"), False)
1644 if lockfd > 0:
1645- logging.warning(_("Unclean dpkg state detected, trying to correct"))
1646- print _("Unclean dpkg state detected, trying to correct")
1647+ logging.warning(
1648+ _("Unclean dpkg state detected, trying to correct"))
1649+ print(_("Unclean dpkg state detected, trying to correct"))
1650 env = copy.copy(os.environ)
1651 env["DEBIAN_FRONTEND"] = "noninteractive"
1652 try:
1653@@ -777,22 +820,23 @@
1654 output = e.output
1655 logging.warning(_("dpkg --configure -a output:\n%s" % output))
1656 else:
1657- logging.debug("Unclean dpkg state, but locked, another package manager working?")
1658-
1659+ logging.debug("Unclean dpkg state, but locked, another package "
1660+ "manager working?")
1661+
1662 # check and get lock
1663 try:
1664 apt_pkg.pkgsystem_lock()
1665- except SystemError, e:
1666+ except SystemError as e:
1667 logging.error(_("Lock could not be acquired (another package "
1668 "manager running?)"))
1669- print _("Cache lock can not be acquired, exiting")
1670+ print(_("Cache lock can not be acquired, exiting"))
1671 sys.exit(1)
1672
1673 # get a cache
1674- cache = UnattendedUpgradesCache(rootdir=rootdir,
1675+ cache = UnattendedUpgradesCache(rootdir=rootdir,
1676 allowed_origins=allowed_origins)
1677 if cache._depcache.broken_count > 0:
1678- print _("Cache has broken packages, exiting")
1679+ print(_("Cache has broken packages, exiting"))
1680 logging.error(_("Cache has broken packages, exiting"))
1681 sys.exit(1)
1682 # speed things up with latest apt
1683@@ -802,13 +846,14 @@
1684 # find out about the packages that are upgradable (in a allowed_origin)
1685 pkgs_to_upgrade = []
1686 pkgs_kept_back = []
1687- pkgs_auto_removable = set([pkg.name for pkg in cache
1688+ pkgs_auto_removable = set([pkg.name for pkg in cache
1689 if pkg.is_auto_removable])
1690
1691 # now do the actual upgrade
1692 for pkg in cache:
1693 if options.debug and pkg.is_upgradable:
1694- logging.debug("Checking: %s (%s)" % (pkg.name, map(str, pkg.candidate.origins)))
1695+ logging.debug("Checking: %s (%s)" % (
1696+ pkg.name, map(str, getattr(pkg.candidate, "origins", []))))
1697 if (pkg.is_upgradable and
1698 not is_pkgname_in_blacklist(pkg.name, blacklisted_pkgs) and
1699 is_allowed_origin(pkg.candidate, allowed_origins)):
1700@@ -818,7 +863,7 @@
1701 blacklisted_pkgs):
1702 # add to packages to upgrade
1703 pkgs_to_upgrade.append(pkg)
1704- # re-eval pkgs_kept_back as the resolver may fail to
1705+ # re-eval pkgs_kept_back as the resolver may fail to
1706 # directly upgrade a pkg, but that may work during
1707 # a subsequent operation, see debian bug #639840
1708 for pkgname in pkgs_kept_back:
1709@@ -830,17 +875,18 @@
1710 logging.debug("sanity check failed")
1711 rewind_cache(cache, pkgs_to_upgrade)
1712 pkgs_kept_back.append(pkg.name)
1713- except SystemError, e:
1714+ except SystemError as e:
1715 # can't upgrade
1716- logging.warning(_("package '%s' upgradable but fails to be marked for upgrade (%s)") % (pkg.name, e))
1717+ logging.warning(
1718+ _("package '%s' upgradable but fails to "
1719+ "be marked for upgrade (%s)") % (pkg.name, e))
1720 rewind_cache(cache, pkgs_to_upgrade)
1721 pkgs_kept_back.append(pkg.name)
1722-
1723
1724 pkgs_to_upgrade.sort(key=lambda p: p.name)
1725 pkgs = "\n".join([pkg.name for pkg in pkgs_to_upgrade])
1726 logging.debug("pkgs that look like they should be upgraded: %s" % pkgs)
1727-
1728+
1729 # download what looks good
1730 if options.debug:
1731 fetcher = apt_pkg.Acquire(apt.progress.text.AcquireProgress())
1732@@ -851,8 +897,8 @@
1733 recs = cache._records
1734 pm = apt_pkg.PackageManager(cache._depcache)
1735 try:
1736- pm.get_archives(fetcher,list,recs)
1737- except SystemError, e:
1738+ pm.get_archives(fetcher, list, recs)
1739+ except SystemError as e:
1740 logging.error(_("GetArchives() failed: '%s'") % e)
1741 res = fetcher.run()
1742 logging.debug("fetch.run() result: %s" % res)
1743@@ -863,15 +909,19 @@
1744 for item in fetcher.items:
1745 logging.debug("%s" % item)
1746 if item.status == item.STAT_ERROR:
1747- print _("An error ocured: '%s'") % item.error_text
1748+ print(_("An error ocured: '%s'") % item.error_text)
1749 logging.error(_("An error ocured: '%s'") % item.error_text)
1750 if not item.complete:
1751- print _("The URI '%s' failed to download, aborting") % item.desc_uri
1752- logging.error(_("The URI '%s' failed to download, aborting") % item.desc_uri)
1753+ print(_("The URI '%s' failed to download, aborting") %
1754+ item.desc_uri)
1755+ logging.error(_("The URI '%s' failed to download, aborting") %
1756+ item.desc_uri)
1757 sys.exit(1)
1758 if not os.path.exists(item.destfile):
1759- print _("Download finished, but file '%s' not there?!?" % item.destfile)
1760- logging.error("Download finished, but file '%s' not there?!?" % item.destfile)
1761+ print(_("Download finished, but file '%s' not there?!?" %
1762+ item.destfile))
1763+ logging.error("Download finished, but file '%s' not "
1764+ "there?!?" % item.destfile)
1765 sys.exit(1)
1766 if not item.is_trusted:
1767 blacklisted_pkgs.append(pkgname_from_deb(item.destfile))
1768@@ -879,18 +929,21 @@
1769 # skip package (means to re-run the whole marking again
1770 # and making sure that the package will not be pulled in by
1771 # some other package again!)
1772- #
1773+ #
1774 # print to stdout to ensure that this message is part of
1775 # the cron mail (only if no summary mail is requested)
1776 email = apt_pkg.config.find("Unattended-Upgrade::Mail", "")
1777 if not email:
1778- print _("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile)
1779+ print(_("Package '%s' has conffile prompt and needs "
1780+ "to be upgraded manually") % pkgname_from_deb(
1781+ item.destfile))
1782 # log to the logfile
1783- logging.warning(_("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile))
1784+ logging.warning(_("Package '%s' has conffile prompt and "
1785+ "needs to be upgraded manually") %
1786+ pkgname_from_deb(item.destfile))
1787 blacklisted_pkgs.append(pkgname_from_deb(item.destfile))
1788 pkgs_kept_back.append(pkgname_from_deb(item.destfile))
1789
1790-
1791 # redo the selection about the packages to upgrade based on the new
1792 # blacklist
1793 logging.debug("blacklist: %s" % blacklisted_pkgs)
1794@@ -904,7 +957,7 @@
1795 pkg.mark_upgrade()
1796 if check_changes_for_sanity(cache, allowed_origins,
1797 blacklisted_pkgs):
1798- pkgs_to_upgrade.append(pkg)
1799+ pkgs_to_upgrade.append(pkg)
1800 else:
1801 if not (pkg.name in pkgs_kept_back):
1802 pkgs_kept_back.append(pkg.name)
1803@@ -916,23 +969,26 @@
1804 logging.debug("dpkg is configured not to cause conffile prompts")
1805
1806 # do auto-remove
1807- if apt_pkg.config.find_b("Unattended-Upgrade::Remove-Unused-Dependencies", False):
1808- now_auto_removable = set([pkg.name for pkg in cache
1809+ if apt_pkg.config.find_b(
1810+ "Unattended-Upgrade::Remove-Unused-Dependencies", False):
1811+ now_auto_removable = set([pkg.name for pkg in cache
1812 if pkg.is_auto_removable])
1813- for pkgname in now_auto_removable-pkgs_auto_removable:
1814+ for pkgname in now_auto_removable - pkgs_auto_removable:
1815 logging.debug("marking %s for remove" % pkgname)
1816 cache[pkgname].mark_delete()
1817 logging.info(_("Packages that are auto removed: '%s'") %
1818- " ".join(now_auto_removable-pkgs_auto_removable))
1819+ " ".join(now_auto_removable - pkgs_auto_removable))
1820
1821- logging.debug("InstCount=%i DelCount=%i BrokenCout=%i" % (cache._depcache.inst_count, cache._depcache.del_count, cache._depcache.broken_count))
1822+ logging.debug("InstCount=%i DelCount=%i BrokenCount=%i" % (
1823+ cache._depcache.inst_count, cache._depcache.del_count,
1824+ cache._depcache.broken_count))
1825
1826 # exit if there is nothing to do and nothing to report
1827 if (len(pkgs_to_upgrade) == 0) and (len(pkgs_kept_back) == 0):
1828 logging.info(_("No packages found that can be upgraded unattended"))
1829 return
1830
1831- # check if its configured for install on shutdown, if so, the
1832+ # check if its configured for install on shutdown, if so, the
1833 # environment UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN will
1834 # be set by the unatteded-upgrades-shutdown script
1835 if (not "UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN" in os.environ and
1836@@ -944,7 +1000,7 @@
1837 # check if we are in dry-run mode
1838 if options.dry_run:
1839 logging.info("Option --dry-run given, *not* performing real actions")
1840- apt_pkg.config.set("Debug::pkgDPkgPM","1")
1841+ apt_pkg.config.set("Debug::pkgDPkgPM", "1")
1842
1843 # do the install based on the new list of pkgs
1844 pkgs = " ".join([pkg.name for pkg in pkgs_to_upgrade])
1845@@ -972,17 +1028,18 @@
1846 pkgs, pkg_install_success, pkgs_kept_back, mem_log, logfile_dpkg)
1847
1848 # auto-reboot (if required and the config for this is set
1849- if (apt_pkg.config.find_b("Unattended-Upgrade::Automatic-Reboot", False) and
1850+ if (apt_pkg.config.find_b(
1851+ "Unattended-Upgrade::Automatic-Reboot", False) and
1852 os.path.exists(REBOOT_REQUIRED_FILE)):
1853 if shutdown_lock > 0:
1854 os.close(shutdown_lock)
1855 logging.warning("Found %s, rebooting" % REBOOT_REQUIRED_FILE)
1856 subprocess.call(["/sbin/reboot"])
1857-
1858+
1859
1860 if __name__ == "__main__":
1861- localesApp="unattended-upgrades"
1862- localesDir="/usr/share/locale"
1863+ localesApp = "unattended-upgrades"
1864+ localesDir = "/usr/share/locale"
1865 gettext.bindtextdomain(localesApp, localesDir)
1866 gettext.textdomain(localesApp)
1867
1868@@ -996,19 +1053,20 @@
1869 help=_("Simulation, download but do not install"))
1870 parser.add_option("", "--minimal_upgrade_steps",
1871 action="store_true", default=False,
1872- help=_("Upgrade in minimal steps (and allow interrupting with SIGINT"))
1873+ help=_("Upgrade in minimal steps (and allow "
1874+ "interrupting with SIGINT"))
1875 (options, args) = parser.parse_args()
1876
1877 if os.getuid() != 0:
1878- print _("You need to be root to run this application")
1879+ print(_("You need to be root to run this application"))
1880 sys.exit(1)
1881
1882 # nice & ionce
1883 os.nice(19)
1884- IONICE="/usr/bin/ionice"
1885+ IONICE = "/usr/bin/ionice"
1886 if os.path.exists(IONICE):
1887 with open(os.devnull, "w") as fstderr:
1888- subprocess.call([IONICE, "-c3", "-p",str(os.getpid())],
1889+ subprocess.call([IONICE, "-c3", "-p", str(os.getpid())],
1890 stderr=fstderr)
1891
1892 # ensure that we are not killed when the terminal goes away e.g. on
1893
1894=== modified file 'unattended-upgrade-shutdown'
1895--- unattended-upgrade-shutdown 2012-04-26 11:40:46 +0000
1896+++ unattended-upgrade-shutdown 2012-10-05 14:59:30 +0000
1897@@ -1,4 +1,4 @@
1898-#!/usr/bin/python
1899+#!/usr/bin/python3
1900 # Copyright (c) 2009 Canonical Ltd
1901 #
1902 # AUTHOR:
1903@@ -141,8 +141,8 @@
1904 os.kill(pid, signal.SIGUSR1)
1905 # show log
1906 log_progress()
1907- time.sleep(5)
1908- if (time.time() - start_time) > options.delay*60:
1909+ time.sleep(5)
1910+ if (time.time() - start_time) > options.delay*60:
1911 logging.warning(_("Giving up on lockfile after %s delay") % options.delay)
1912 sys.exit(1)
1913

Subscribers

People subscribed via source and target branches

to all changes: