Merge lp:~takluyver/unattended-upgrades/py3 into lp:~ubuntu-core-dev/unattended-upgrades/ubuntu

Proposed by Thomas Kluyver
Status: Merged
Approved by: Barry Warsaw
Approved revision: 285
Merge reported by: Barry Warsaw
Merged at revision: not available
Proposed branch: lp:~takluyver/unattended-upgrades/py3
Merge into: lp:~ubuntu-core-dev/unattended-upgrades/ubuntu
Diff against target: 712 lines (+115/-93)
18 files modified
.bzrignore (+2/-0)
debian/changelog (+4/-1)
debian/control (+4/-4)
debian/rules (+13/-11)
debian/unattended-upgrades.init (+1/-1)
pm/sleep.d/10_unattended-upgrades-hibernate (+1/-1)
test/Makefile (+2/-2)
test/create_debug_lock.py (+1/-1)
test/test_against_real_archive.py (+9/-3)
test/test_conffile.py (+1/-1)
test/test_in_chroot.py (+9/-9)
test/test_logdir.py (+1/-1)
test/test_mail.py (+16/-9)
test/test_minimal_partitions.py (+2/-5)
test/test_origin_pattern.py (+1/-1)
test/test_substitute.py (+2/-2)
unattended-upgrade (+43/-38)
unattended-upgrade-shutdown (+3/-3)
To merge this branch: bzr merge lp:~takluyver/unattended-upgrades/py3
Reviewer Review Type Date Requested Status
Barry Warsaw (community) Approve
Michael Vogt upload to debian Pending
Review via email: mp+110684@code.launchpad.net

Description of the change

As part of Ubuntu's push for Python 3 in Quantal (https://blueprints.launchpad.net/ubuntu/+spec/foundations-q-python-versions), this makes unattended-upgrades use Python 3.

The tests pass, and I've checked that it contains equivalent files to the current package (http://packages.ubuntu.com/quantal/all/unattended-upgrades/filelist). I'm not sure how to test unattended-upgrades-shutdown, but I've ensured that the syntax is valid, and inspecting the file, it doesn't look like it will require any other changes for Python 3.

To post a comment you must log in.
Revision history for this message
Thomas Kluyver (takluyver) wrote :

I've just noticed that test_in_chroot.py isn't run with the other tests. It appears to fail on Python 2. How much attention should I pay to it?

278. By Michael Vogt

* po/da.po:
  - updated, thanks to Joe Dalton, closes: #677804

279. By Michael Vogt

* debian/unattended-upgrades.init:
  - use new style lsb-init output, closes: #678030

280. By Michael Vogt

honor verbose

Revision history for this message
Barry Warsaw (barry) wrote :

Looks like there are some text conflicts as well, but I can try to fix those.

Revision history for this message
Barry Warsaw (barry) wrote :

Oh also, the conversion to bytes in send_summary_mail() isn't right. It's generally accepted wisdom that in Python 3, Popen() should be passed universal_newlines=True which gives you unicodes. I think that's the right thing to do in this case.

Revision history for this message
Barry Warsaw (barry) wrote :

Thomas, thanks for taking this work on! I appreciate everything you can do to
help us in our porting efforts. A few comments, and then I'll work on merging
this for you.

 - I don't know how to test unattended-upgrades-shutdown, but I'll see if I
   can come up with something.

 - How hard would it be to fix the failing Python 2 test? If it fails in Py2
   it would be nice to fix, but I don't think it should necessarily block your
   work.

 - Note that unless you're holding out the possibility to revert to Python 2,
   or if you're being annoyed by pyflakes warnings, you really don't need to
   future import print_function for Python 3.

 - Line 433 would probably be better rewritten:

    with open(prefix + conf_file, 'rb') as fp:
        current_md5 = fp.read()

   I can fix that for you when I merge your branch.

Other than that, the diff looks pretty good.

Revision history for this message
Barry Warsaw (barry) wrote :

Also, test_against_real_archive fails for me even in unchanged trunk:

======================================================================
FAIL: test_against_real_archive (__main__.TestAgainstRealArchive)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "./test_against_real_archive.py", line 47, in test_against_real_archive
    self.assertFalse(" ERROR " in log)
AssertionError: True is not false

----------------------------------------------------------------------
Ran 1 test in 9.248s

281. By Barry Warsaw

Merge Thomas's branch: Port to Python 3
- Additional fixes by Barry

Revision history for this message
Barry Warsaw (barry) wrote :

Thomas, for now I'm going to mark this branch as needs fixing. Please look at my branch, which merges yours into trunk and contains additional fixes that will be necessary. If you can get the remaining tests to pass, I'll be happy to re-review the branch and sponsor it for you.

lp:~barry/unattended-upgrades/py3merge

review: Needs Fixing
Revision history for this message
Thomas Kluyver (takluyver) wrote :

Thanks Barry,

On 19 June 2012 20:25, Barry Warsaw <email address hidden> wrote:
>  - How hard would it be to fix the failing Python 2 test?  If it fails in Py2
>   it would be nice to fix, but I don't think it should necessarily block your
>   work.

I should have been clearer about this - I meant 'it fails *even* in
Python 2, so I haven't tried it in Python 3 yet'. To further
complicate matters, it tests in a Lucid chroot, and there's no
python3-apt in Lucid. I don't know whether testing in an old version
is an intentional way to make sure there's updates available, or just
because the test was written then and hasn't been changed.

For reference, I've re-run it (in Python 2) and put the last part of
the output at https://gist.github.com/2957247

>  - Note that unless you're holding out the possibility to revert to Python 2,
>   or if you're being annoyed by pyflakes warnings, you really don't need to
>   future import print_function for Python 3.

Do any other distributions use unattended-upgrades? If anyone wants to
keep running it in Python 2, it's very easy for me to enable that. If
not, I agree that it's slightly tidier not to.

>  - Line 433 would probably be better rewritten:
>
>    with open(prefix + conf_file, 'rb') as fp:
>        current_md5 = fp.read()
>
>   I can fix that for you when I merge your branch.

I see you did fix it; thanks.

Thomas

Revision history for this message
Thomas Kluyver (takluyver) wrote :

Thanks for the tip about Popen(), I didn't know about that argument. It seems rather unintuitive to have universal_newlines control text/bytes mode, though.

I've checked out your branch - I don't see the failure in test_against_real_archive.py, either on Python 3 or 2. Full output is at https://gist.github.com/2957277

Revision history for this message
Barry Warsaw (barry) wrote :

On Jun 20, 2012, at 12:15 AM, Thomas Kluyver wrote:

>I've checked out your branch - I don't see the failure in
>test_against_real_archive.py, either on Python 3 or 2. Full output is at
>https://gist.github.com/2957277

That probably means it's dependent on the environment. Something in my
environment (on precise and quantal, on both a normal desktop and chroot) is
causing the test to fail. That plus the fact that the test hits the network
tell me that it's not a very good test.

The problem is, if I want to sponsor this for you, I have to build the source
package. To do that, I'd have to disable the test since the source package
won't build with a failing test. Maybe that's the best we can do with such a
bad test.

It's not clear to me what this test is actually trying to do though. Do you
think you could take a crack at improving the test so that it isn't dependent
on the environment, and/or that it doesn't hit the network? Failing that, we
might just have to bite the bullet and disable the test.

As for continuing to support Python 2, perhaps the only reason to do so is if
it needs to be backported to earlier versions that don't have Python 3. If
not, then I personally think it would be fine to drop it.

282. By Thomas Kluyver

Fix subprocess communication on Python 3

283. By Thomas Kluyver

Disable test that requires network access

284. By Thomas Kluyver

Remove Python 2 compatible imports

Revision history for this message
Thomas Kluyver (takluyver) wrote :

I think the nature of that test needs network communications - 'against real archive' seems to mean the Ubuntu package archive. I've disabled it so that "cd test/; make" doesn't see it (it checks the executable flag on the files). The package building doesn't appear to run any tests, however.

I've also dropped the backwards compatible imports, so it will only work with Python 3.

Revision history for this message
Barry Warsaw (barry) wrote :

On Jun 24, 2012, at 03:46 PM, Thomas Kluyver wrote:

>I think the nature of that test needs network communications - 'against real
>archive' seems to mean the Ubuntu package archive. I've disabled it so that
>"cd test/; make" doesn't see it (it checks the executable flag on the
>files). The package building doesn't appear to run any tests, however.
>
>I've also dropped the backwards compatible imports, so it will only work with
>Python 3.

Quick response: I'm now getting a text conflict against trunk in
debian/unattended-upgrades.init. Can you please resolve that?

I was able to build the package locally and everything else looks fine, so
once you push an non-conflicting update, I'll try to sponsor this for you.

Thanks for your work on porting this to Python 3!

285. By Thomas Kluyver

Merge trunk

Revision history for this message
Thomas Kluyver (takluyver) wrote :

Thanks, Barry. I've merged in trunk and resolved the conflict.

Revision history for this message
Barry Warsaw (barry) wrote :

Thanks Thomas, looks great. I've pushed the merge to trunk, but it's up to Michael to upload the new package. I think it has to go to Debian first, and then it'll get sync'd into Quantal.

Revision history for this message
Barry Warsaw (barry) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file '.bzrignore'
--- .bzrignore 1970-01-01 00:00:00 +0000
+++ .bzrignore 2012-06-25 20:04:38 +0000
@@ -0,0 +1,2 @@
1__pycache__
2build
03
=== modified file 'debian/changelog'
--- debian/changelog 2012-06-25 07:11:57 +0000
+++ debian/changelog 2012-06-25 20:04:38 +0000
@@ -16,6 +16,9 @@
16 * debian/unattended-upgrades.init:16 * debian/unattended-upgrades.init:
17 - fixes new style lsb-init output, closes: #67803017 - fixes new style lsb-init output, closes: #678030
1818
19 [ Thomas Kluyver ]
20 * Port to Python 3
21
19 -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 25 Jun 2012 08:42:23 +020022 -- Michael Vogt <michael.vogt@ubuntu.com> Mon, 25 Jun 2012 08:42:23 +0200
2023
21unattended-upgrades (0.78) unstable; urgency=low24unattended-upgrades (0.78) unstable; urgency=low
@@ -28,7 +31,7 @@
28 - updated, thanks to Joe Dalton, closes: #67780431 - updated, thanks to Joe Dalton, closes: #677804
29 * po/de.po:32 * po/de.po:
30 - updated, thanks to Chris Leick (closes: #678204)33 - updated, thanks to Chris Leick (closes: #678204)
31 34
32 [ Teodor MICU ]35 [ Teodor MICU ]
33 * debian/unattended-upgrades.init:36 * debian/unattended-upgrades.init:
34 - use new style lsb-init output, closes: #67803037 - use new style lsb-init output, closes: #678030
3538
=== modified file 'debian/control'
--- debian/control 2012-06-19 15:26:37 +0000
+++ debian/control 2012-06-25 20:04:38 +0000
@@ -3,14 +3,14 @@
3Priority: optional3Priority: optional
4Maintainer: Michael Vogt <michael.vogt@ubuntu.com>4Maintainer: Michael Vogt <michael.vogt@ubuntu.com>
5Build-Depends: debhelper (>= 7.0.50~), po-debconf, lsb-release5Build-Depends: debhelper (>= 7.0.50~), po-debconf, lsb-release
6Build-Depends-Indep: python (>= 2.6.6-3~), python-distutils-extra6Build-Depends-Indep: python3, python3-distutils-extra
7Standards-Version: 3.8.37Standards-Version: 3.9.3
8Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/unattended-upgrades/ubuntu/8Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/unattended-upgrades/ubuntu/
99
10Package: unattended-upgrades10Package: unattended-upgrades
11Architecture: all11Architecture: all
12Depends: ${shlibs:Depends}, ${misc:Depends}, debconf, python, 12Depends: ${shlibs:Depends}, ${misc:Depends}, debconf, python3,
13 python-apt (>= 0.7.90), apt-utils, apt, ucf, lsb-release, 13 python3-apt (>= 0.7.90), apt-utils, apt, ucf, lsb-release,
14 lsb-base (>= 3.2-14)14 lsb-base (>= 3.2-14)
15Suggests: bsd-mailx15Suggests: bsd-mailx
16Description: automatic installation of security upgrades16Description: automatic installation of security upgrades
1717
=== modified file 'debian/rules'
--- debian/rules 2011-11-09 19:20:50 +0000
+++ debian/rules 2012-06-25 20:04:38 +0000
@@ -3,24 +3,26 @@
3DIST=$(shell /usr/bin/lsb_release -i -s)3DIST=$(shell /usr/bin/lsb_release -i -s)
44
5%:5%:
6 dh $@ --with python26 dh $@ --with python3
77
8override_dh_auto_build:8override_dh_auto_build:
9 # copy the right template into place9 # copy the right template into place
10 cp data/50unattended-upgrades.$(DIST) data/50unattended-upgrades10 cp data/50unattended-upgrades.$(DIST) data/50unattended-upgrades
11 dh_auto_build11 python3 setup.py build
12
13override_dh_auto_install:
14 python3 setup.py install \
15 --root=$(CURDIR)/debian/unattended-upgrades \
16 --install-layout=deb
1217
13override_dh_auto_clean:18override_dh_auto_clean:
14 # Sanity-check before upload.19 # Sanity-check before upload.
15 set -e; if [ -e /usr/lib/python$(PYVER)/py_compile.py ]; then \20 set -e; for f in unattended-upgrade unattended-upgrade-shutdown; do \
16 for f in unattended-upgrade unattended-upgrade-shutdown; do \21 ln -nsf $$f $$f.py; \
17 ln -nsf $$f $$f.py; \22 py3compile $$f.py; \
18 python$(PYVER) /usr/lib/python$(PYVER)/py_compile.py \23 rm -f $$f.py; \
19 $$f.py; \24 done
20 rm -f $$f.py; \25 python3 setup.py clean -a
21 done; \
22 fi
23 dh_auto_clean
2426
25override_dh_installinit:27override_dh_installinit:
26 # we do not want to run the init script in the postinst/prerm, its28 # we do not want to run the init script in the postinst/prerm, its
2729
=== modified file 'debian/unattended-upgrades.init'
--- debian/unattended-upgrades.init 2012-06-25 07:07:39 +0000
+++ debian/unattended-upgrades.init 2012-06-25 20:04:38 +0000
@@ -33,7 +33,7 @@
33stop)33stop)
34 if [ -e $SHUTDOWN_HELPER ]; then34 if [ -e $SHUTDOWN_HELPER ]; then
35 [ "$VERBOSE" != "no" ] && log_action_begin_msg "Checking for running $DESC"35 [ "$VERBOSE" != "no" ] && log_action_begin_msg "Checking for running $DESC"
36 python $SHUTDOWN_HELPER36 python3 $SHUTDOWN_HELPER
37 [ "$VERBOSE" != "no" ] && log_action_end_msg $? "$NAME"37 [ "$VERBOSE" != "no" ] && log_action_end_msg $? "$NAME"
38 fi38 fi
39 ;;39 ;;
4040
=== modified file 'pm/sleep.d/10_unattended-upgrades-hibernate'
--- pm/sleep.d/10_unattended-upgrades-hibernate 2011-11-08 16:56:58 +0000
+++ pm/sleep.d/10_unattended-upgrades-hibernate 2012-06-25 20:04:38 +0000
@@ -17,7 +17,7 @@
17case "${1}" in17case "${1}" in
18 hibernate)18 hibernate)
19 if [ -e $SHUTDOWN_HELPER ]; then19 if [ -e $SHUTDOWN_HELPER ]; then
20 python $SHUTDOWN_HELPER20 python3 $SHUTDOWN_HELPER
21 fi21 fi
22 ;;22 ;;
23 resume|thaw)23 resume|thaw)
2424
=== modified file 'test/Makefile'
--- test/Makefile 2011-10-07 09:22:19 +0000
+++ test/Makefile 2012-06-25 20:04:38 +0000
@@ -6,9 +6,9 @@
6 set -e; \6 set -e; \
7 find . -name 'test_*.py' | \7 find . -name 'test_*.py' | \
8 while read file; do \8 while read file; do \
9 echo "Running $$file"; \
10 if [ -x $$file ]; then \9 if [ -x $$file ]; then \
11 python $$file ; \10 echo "Running $$file"; \
11 python3 $$file ; \
12 fi \12 fi \
13 done13 done
1414
1515
=== modified file 'test/create_debug_lock.py'
--- test/create_debug_lock.py 2011-06-16 07:10:07 +0000
+++ test/create_debug_lock.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
2#2#
3# create a lock file so that unattended-upgrades-shutdown pauses3# create a lock file so that unattended-upgrades-shutdown pauses
4# on shutdown -- useful for testing4# on shutdown -- useful for testing
55
=== modified file 'test/test_against_real_archive.py' (properties changed: +x to -x)
--- test/test_against_real_archive.py 2012-02-28 10:48:18 +0000
+++ test/test_against_real_archive.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,9 @@
1#!/usr/bin/python1#!/usr/bin/python3
2"""Test unattended_upgrades against the real archive in a chroot.
3
4Note that this test is not run by the makefile in this folder, as it requires
5network access, and it fails in some situations (unclear which).
6"""
27
3import apt8import apt
4import apt_pkg9import apt_pkg
@@ -42,9 +47,10 @@
42 res = unattended_upgrade.main(options, os.path.abspath("./aptroot"))47 res = unattended_upgrade.main(options, os.path.abspath("./aptroot"))
43 # check if the log file exists48 # check if the log file exists
44 self.assertTrue(os.path.exists(logfile))49 self.assertTrue(os.path.exists(logfile))
45 log = open(logfile).read()50 with open(logfile) as fp:
51 log = fp.read()
46 # check that stuff worked52 # check that stuff worked
47 self.assertFalse(" ERROR " in log)53 self.assertFalse(" ERROR " in log, log)
48 # check if we actually have the expected ugprade in it54 # check if we actually have the expected ugprade in it
49 self.assertTrue(55 self.assertTrue(
50 re.search("INFO Packages that are upgraded:.*awstats", log))56 re.search("INFO Packages that are upgraded:.*awstats", log))
5157
=== modified file 'test/test_conffile.py'
--- test/test_conffile.py 2011-04-28 16:29:19 +0000
+++ test/test_conffile.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt_pkg3import apt_pkg
4import logging4import logging
55
=== modified file 'test/test_in_chroot.py'
--- test/test_in_chroot.py 2012-01-02 13:14:02 +0000
+++ test/test_in_chroot.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt3import apt
4import logging4import logging
@@ -56,7 +56,7 @@
56class TestUnattendedUpgrade(unittest.TestCase):56class TestUnattendedUpgrade(unittest.TestCase):
5757
58 def _create_new_debootstrap_tarball(self, tarball, target):58 def _create_new_debootstrap_tarball(self, tarball, target):
59 print "creating initial test tarball, this is needed only once"59 print("creating initial test tarball, this is needed only once")
60 # force i38660 # force i386
61 subprocess.call(["debootstrap",61 subprocess.call(["debootstrap",
62 "--arch=%s" % ARCH,62 "--arch=%s" % ARCH,
@@ -73,7 +73,7 @@
73 subprocess.call(["tar", "xzf", tarball])73 subprocess.call(["tar", "xzf", tarball])
7474
75 def test_normal_upgrade(self):75 def test_normal_upgrade(self):
76 print "Running normal unattended upgrade in chroot"76 print("Running normal unattended upgrade in chroot")
77 options = MockOptions()77 options = MockOptions()
78 options.minimal_upgrade_steps = False78 options.minimal_upgrade_steps = False
79 # run it79 # run it
@@ -82,7 +82,7 @@
82 self.assertTrue(self._verify_install_log_in_real_chroot(target))82 self.assertTrue(self._verify_install_log_in_real_chroot(target))
8383
84 def test_minimal_steps_upgrade(self):84 def test_minimal_steps_upgrade(self):
85 print "Running minimal steps unattended upgrade in chroot"85 print("Running minimal steps unattended upgrade in chroot")
86 options = MockOptions()86 options = MockOptions()
87 options.minimal_upgrade_steps = True87 options.minimal_upgrade_steps = True
88 # run it88 # run it
@@ -91,7 +91,7 @@
91 self.assertTrue(self._verify_install_log_in_real_chroot(target))91 self.assertTrue(self._verify_install_log_in_real_chroot(target))
9292
93 def test_upgrade_on_shutdown_upgrade(self):93 def test_upgrade_on_shutdown_upgrade(self):
94 print "Running unattended upgrade on shutdown (download and install) in chroot"94 print("Running unattended upgrade on shutdown (download and install) in chroot")
95 # ensure that it actually installs in shutdown env mode95 # ensure that it actually installs in shutdown env mode
96 options = MockOptions()96 options = MockOptions()
97 os.environ["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"97 os.environ["UNATTENDED_UPGRADES_FORCE_INSTALL_ON_SHUTDOWN"] = "1"
@@ -121,7 +121,7 @@
121 and does some basic verifications121 and does some basic verifications
122 """122 """
123 if os.getuid() != 0:123 if os.getuid() != 0:
124 print "Skipping because uid != 0"124 print("Skipping because uid != 0")
125 return125 return
126126
127 # clear to avoid pollution in the chroot127 # clear to avoid pollution in the chroot
@@ -171,7 +171,7 @@
171 if pid == apid:171 if pid == apid:
172 ret = os.WEXITSTATUS(status)172 ret = os.WEXITSTATUS(status)
173 break173 break
174 #print "*******************", all_progress174 #print("*******************", all_progress)
175 self.assertEqual(ret, 0)175 self.assertEqual(ret, 0)
176 # this number is a bit random, we just want to be sure we have 176 # this number is a bit random, we just want to be sure we have
177 # progress data177 # progress data
@@ -183,7 +183,7 @@
183 # examine log183 # examine log
184 log = self._get_lockfile_location(target)184 log = self._get_lockfile_location(target)
185 logfile = open(log).read()185 logfile = open(log).read()
186 #print logfile186 #print(logfile)
187 NEEDLE_PKG="ca-certificates"187 NEEDLE_PKG="ca-certificates"
188 if not re.search(188 if not re.search(
189 "Packages that are upgraded:.*%s" % NEEDLE_PKG, logfile):189 "Packages that are upgraded:.*%s" % NEEDLE_PKG, logfile):
@@ -198,7 +198,7 @@
198 if not "Preparing to replace %s" % NEEDLE_PKG in dpkg_logfile:198 if not "Preparing to replace %s" % NEEDLE_PKG in dpkg_logfile:
199 logging.warn("Did not find %s upgrade in the dpkg.log" % NEEDLE_PKG)199 logging.warn("Did not find %s upgrade in the dpkg.log" % NEEDLE_PKG)
200 return False200 return False
201 #print dpkg_logfile201 #print(dpkg_logfile)
202 return True202 return True
203203
204204
205205
=== modified file 'test/test_logdir.py'
--- test/test_logdir.py 2011-03-04 15:04:54 +0000
+++ test/test_logdir.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt_pkg3import apt_pkg
4import logging4import logging
55
=== modified file 'test/test_mail.py'
--- test/test_mail.py 2011-02-03 19:50:16 +0000
+++ test/test_mail.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt3import apt
4import apt_pkg4import apt_pkg
@@ -7,7 +7,7 @@
7import unittest7import unittest
8import sys8import sys
99
10from StringIO import StringIO10from io import StringIO
1111
12import unattended_upgrade12import unattended_upgrade
13import unattended_upgrade13import unattended_upgrade
@@ -36,7 +36,8 @@
36 pkgs_kept_back = []36 pkgs_kept_back = []
37 mem_log = StringIO("mem_log text")37 mem_log = StringIO("mem_log text")
38 logfile_dpkg = "./apt-term.log"38 logfile_dpkg = "./apt-term.log"
39 open("./apt-term.log", "w").write("logfile_dpkg text")39 with open("./apt-term.log", "w") as fp:
40 fp.write("logfile_dpkg text")
40 return (pkgs, res, pkgs_kept_back, mem_log, logfile_dpkg)41 return (pkgs, res, pkgs_kept_back, mem_log, logfile_dpkg)
4142
42 def _verify_common_mail_content(self, mail_txt):43 def _verify_common_mail_content(self, mail_txt):
@@ -45,16 +46,19 @@
45 self.assertTrue("Packages that are upgraded:\n 2vcard" in mail_txt)46 self.assertTrue("Packages that are upgraded:\n 2vcard" in mail_txt)
4647
47 def test_summary_mail_reboot(self):48 def test_summary_mail_reboot(self):
48 open("./reboot-required","w").write("")49 with open("./reboot-required","w") as fp:
50 fp.write("")
49 send_summary_mail(*self._return_mock_data())51 send_summary_mail(*self._return_mock_data())
50 os.unlink("./reboot-required")52 os.unlink("./reboot-required")
51 mail_txt = open("mail.txt").read()53 with open("mail.txt") as fp:
54 mail_txt = fp.read()
52 self.assertTrue("[reboot required]" in mail_txt)55 self.assertTrue("[reboot required]" in mail_txt)
53 self._verify_common_mail_content(mail_txt)56 self._verify_common_mail_content(mail_txt)
54 57
55 def test_summary_mail_no_reboot(self):58 def test_summary_mail_no_reboot(self):
56 send_summary_mail(*self._return_mock_data())59 send_summary_mail(*self._return_mock_data())
57 mail_txt = open("mail.txt").read()60 with open("mail.txt") as fp:
61 mail_txt = fp.read()
58 self.assertFalse("[reboot required]" in mail_txt)62 self.assertFalse("[reboot required]" in mail_txt)
59 self._verify_common_mail_content(mail_txt)63 self._verify_common_mail_content(mail_txt)
60 64
@@ -63,18 +67,21 @@
63 # for both success and failure67 # for both success and failure
64 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "false")68 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "false")
65 send_summary_mail(*self._return_mock_data(successful=True))69 send_summary_mail(*self._return_mock_data(successful=True))
66 self._verify_common_mail_content(open("mail.txt").read())70 with open("mail.txt") as fp:
71 self._verify_common_mail_content(fp.read())
67 os.remove("mail.txt")72 os.remove("mail.txt")
68 # now with a simulated failure73 # now with a simulated failure
69 send_summary_mail(*self._return_mock_data(successful=False))74 send_summary_mail(*self._return_mock_data(successful=False))
70 self._verify_common_mail_content(open("mail.txt").read())75 with open("mail.txt") as fp:
76 self._verify_common_mail_content(fp.read())
71 os.remove("mail.txt")77 os.remove("mail.txt")
72 # now test with "MailOnlyOnError"78 # now test with "MailOnlyOnError"
73 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "true")79 apt_pkg.config.set("Unattended-Upgrade::MailOnlyOnError", "true")
74 send_summary_mail(*self._return_mock_data(successful=True))80 send_summary_mail(*self._return_mock_data(successful=True))
75 self.assertFalse(os.path.exists("mail.txt"))81 self.assertFalse(os.path.exists("mail.txt"))
76 send_summary_mail(*self._return_mock_data(successful=False))82 send_summary_mail(*self._return_mock_data(successful=False))
77 mail_txt = open("mail.txt").read()83 with open("mail.txt") as fp:
84 mail_txt = fp.read()
78 self._verify_common_mail_content(mail_txt)85 self._verify_common_mail_content(mail_txt)
79 self.assertTrue("Unattended upgrade returned: False" in mail_txt)86 self.assertTrue("Unattended upgrade returned: False" in mail_txt)
80 self.assertTrue(os.path.exists("mail.txt"))87 self.assertTrue(os.path.exists("mail.txt"))
8188
=== modified file 'test/test_minimal_partitions.py'
--- test/test_minimal_partitions.py 2011-11-18 10:46:15 +0000
+++ test/test_minimal_partitions.py 2012-06-25 20:04:38 +0000
@@ -1,12 +1,9 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt3import apt
4import apt_pkg4import apt_pkg
5import os5import os
6import logging
7import unittest6import unittest
8import sys
9import time
107
11import unattended_upgrade8import unattended_upgrade
129
@@ -18,7 +15,7 @@
18 15
19 # overwrite to log the data16 # overwrite to log the data
20 def status_change(self, pkg, percent, status):17 def status_change(self, pkg, percent, status):
21 print pkg, percent18 print(pkg, percent)
22 self.DATA.append([pkg, percent])19 self.DATA.append([pkg, percent])
2320
24class TestMinimalPartitions(unittest.TestCase):21class TestMinimalPartitions(unittest.TestCase):
2522
=== modified file 'test/test_origin_pattern.py'
--- test/test_origin_pattern.py 2011-11-22 12:54:47 +0000
+++ test/test_origin_pattern.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt3import apt
4import apt_pkg4import apt_pkg
55
=== modified file 'test/test_substitute.py'
--- test/test_substitute.py 2011-02-04 11:05:12 +0000
+++ test/test_substitute.py 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
22
3import apt3import apt
4import apt_pkg4import apt_pkg
@@ -7,7 +7,7 @@
7import unittest7import unittest
8import sys8import sys
99
10from StringIO import StringIO10from io import StringIO
1111
12import unattended_upgrade12import unattended_upgrade
13from unattended_upgrade import substitute, get_allowed_origins13from unattended_upgrade import substitute, get_allowed_origins
1414
=== modified file 'unattended-upgrade'
--- unattended-upgrade 2012-05-31 07:51:04 +0000
+++ unattended-upgrade 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
2# Copyright (c) 2005-2012 Canonical Ltd2# Copyright (c) 2005-2012 Canonical Ltd
3#3#
4# AUTHOR:4# AUTHOR:
@@ -20,11 +20,10 @@
20# along with unattended-upgrades; if not, write to the Free Software20# along with unattended-upgrades; if not, write to the Free Software
21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA21# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22#22#
23
24import apt_inst23import apt_inst
25import apt_pkg24import apt_pkg
2625
27import ConfigParser26import configparser
28import copy27import copy
29import datetime28import datetime
30import fcntl29import fcntl
@@ -33,7 +32,7 @@
33import string32import string
34import sys33import sys
3534
36from StringIO import StringIO35from io import StringIO
37from optparse import OptionParser36from optparse import OptionParser
38from subprocess import Popen, PIPE37from subprocess import Popen, PIPE
3938
@@ -112,9 +111,8 @@
112 LOG = PROGRESS_LOG 111 LOG = PROGRESS_LOG
113112
114 def status_change(self, pkg, percent, status):113 def status_change(self, pkg, percent, status):
115 f=open(self.LOG, "w")114 with open(self.LOG, "w") as f:
116 f.write(_("Progress: %s %% (%s)") % (percent, pkg))115 f.write(_("Progress: %s %% (%s)") % (percent, pkg))
117 f.close()
118116
119 def _fixup_fds(self):117 def _fixup_fds(self):
120 required_fds = [ 0, 1, 2, # stdin, stdout, stderr118 required_fds = [ 0, 1, 2, # stdin, stdout, stderr
@@ -135,19 +133,19 @@
135 try:133 try:
136 fd = int(fdname)134 fd = int(fdname)
137 except Exception as e:135 except Exception as e:
138 print "ERROR: can not get fd for '%s'" % fdname136 print("ERROR: can not get fd for '%s'" % fdname)
139 if fd in required_fds:137 if fd in required_fds:
140 continue138 continue
141 try:139 try:
142 os.close(fd)140 os.close(fd)
143 #print "closed: ", fd141 #print("closed: ", fd)
144 except OSError as e:142 except OSError as e:
145 # there will be one fd that can not be closed143 # there will be one fd that can not be closed
146 # as its the fd from pythons internal diropen()144 # as its the fd from pythons internal diropen()
147 # so its ok to ignore one close error145 # so its ok to ignore one close error
148 error_count += 1146 error_count += 1
149 if error_count > 1:147 if error_count > 1:
150 print "ERROR: os.close(%s): %s" % (fd, e)148 print("ERROR: os.close(%s): %s" % (fd, e))
151149
152 def fork(self):150 def fork(self):
153 pid = os.fork()151 pid = os.fork()
@@ -270,7 +268,7 @@
270 try:268 try:
271 with Unlocked():269 with Unlocked():
272 res = cache.commit(install_progress=iprogress)270 res = cache.commit(install_progress=iprogress)
273 except SystemError,e:271 except SystemError as e:
274 error = e272 error = e
275 if res:273 if res:
276 logging.info(_("All upgrades installed"))274 logging.info(_("All upgrades installed"))
@@ -334,7 +332,7 @@
334 if not res:332 if not res:
335 raise Exception("cache.commit() returned false")333 raise Exception("cache.commit() returned false")
336 cache.open()334 cache.open()
337 except Exception, e:335 except Exception as e:
338 logging.error(_("Installing the upgrades failed!"))336 logging.error(_("Installing the upgrades failed!"))
339 logging.error(_("error message: '%s'") % e)337 logging.error(_("error message: '%s'") % e)
340 logging.error(_("dpkg returned a error! See '%s' for details") % \338 logging.error(_("dpkg returned a error! See '%s' for details") % \
@@ -390,7 +388,7 @@
390 control = apt_inst.DebFile(debfile).control.extractdata("control")388 control = apt_inst.DebFile(debfile).control.extractdata("control")
391 sections = apt_pkg.TagSection(control)389 sections = apt_pkg.TagSection(control)
392 return sections["Package"]390 return sections["Package"]
393 except (IOError, SystemError), e:391 except (IOError, SystemError) as e:
394 logging.error("failed to read deb file '%s' (%s)" % (debfile, e))392 logging.error("failed to read deb file '%s' (%s)" % (debfile, e))
395 # dumb fallback393 # dumb fallback
396 return debfile.split("_")[0]394 return debfile.split("_")[0]
@@ -408,9 +406,9 @@
408 conffiles = section.get("Conffiles")406 conffiles = section.get("Conffiles")
409 # Conffiles:407 # Conffiles:
410 # /etc/bash_completion.d/m-a c7780fab6b14d75ca54e11e992a6c11c408 # /etc/bash_completion.d/m-a c7780fab6b14d75ca54e11e992a6c11c
411 for line in string.split(conffiles,"\n"):409 for line in conffiles.splitlines():
412 logging.debug("conffile line: %s", line)410 logging.debug("conffile line: %s", line)
413 l = string.split(string.strip(line))411 l = line.strip().split()
414 conf_file = l[0]412 conf_file = l[0]
415 md5 = l[1]413 md5 = l[1]
416 if len(l) > 2:414 if len(l) > 2:
@@ -428,7 +426,7 @@
428 # does not have conffiles anymore426 # does not have conffiles anymore
429 deb = apt_inst.DebFile(destFile)427 deb = apt_inst.DebFile(destFile)
430 try:428 try:
431 pkg_conffiles = deb.control.extractdata("conffiles")429 pkg_conffiles = deb.control.extractdata("conffiles").decode('utf-8')
432 except LookupError as e:430 except LookupError as e:
433 logging.debug("No conffiles in %s anymore? (%s)" % (destFile, e))431 logging.debug("No conffiles in %s anymore? (%s)" % (destFile, e))
434 pkg_conffiles = ""432 pkg_conffiles = ""
@@ -437,7 +435,8 @@
437 logging.debug("'%s' not in package conffiles '%s'" % (conf_file, pkg_conffiles))435 logging.debug("'%s' not in package conffiles '%s'" % (conf_file, pkg_conffiles))
438 continue436 continue
439 # test against the installed file437 # test against the installed file
440 current_md5 = apt_pkg.md5sum(open(prefix+conf_file).read())438 with open(prefix+conf_file, 'rb') as fp:
439 current_md5 = apt_pkg.md5sum(fp.read())
441 logging.debug("current md5: %s" % current_md5)440 logging.debug("current md5: %s" % current_md5)
442 # hashes are the same, no conffile prompt441 # hashes are the same, no conffile prompt
443 if current_md5 == md5:442 if current_md5 == md5:
@@ -446,9 +445,12 @@
446 dpkg_cmd = ["dpkg-deb","--fsys-tarfile",destFile]445 dpkg_cmd = ["dpkg-deb","--fsys-tarfile",destFile]
447 tar_cmd = ["tar","-x","-O", "-f","-", "."+conf_file]446 tar_cmd = ["tar","-x","-O", "-f","-", "."+conf_file]
448 md5_cmd = ["md5sum"]447 md5_cmd = ["md5sum"]
449 dpkg_p = Popen(dpkg_cmd, stdout=PIPE)448 dpkg_p = Popen(dpkg_cmd, stdout=PIPE,
450 tar_p = Popen(tar_cmd, stdin=dpkg_p.stdout, stdout=PIPE)449 universal_newlines=True)
451 md5_p = Popen(md5_cmd, stdin=tar_p.stdout, stdout=PIPE)450 tar_p = Popen(tar_cmd, stdin=dpkg_p.stdout, stdout=PIPE,
451 universal_newlines=True)
452 md5_p = Popen(md5_cmd, stdin=tar_p.stdout, stdout=PIPE,
453 universal_newlines=True)
452 pkg_md5sum = md5_p.communicate()[0].split()[0]454 pkg_md5sum = md5_p.communicate()[0].split()[0]
453 logging.debug("pkg_md5sum: %s" % pkg_md5sum)455 logging.debug("pkg_md5sum: %s" % pkg_md5sum)
454 # the md5sum in the deb is unchanged, this will not 456 # the md5sum in the deb is unchanged, this will not
@@ -496,7 +498,7 @@
496 """ deal with apt-listchanges """498 """ deal with apt-listchanges """
497 if os.path.exists(conf):499 if os.path.exists(conf):
498 # check if mail is used by apt-listchanges500 # check if mail is used by apt-listchanges
499 cf = ConfigParser.ConfigParser()501 cf = configparser.ConfigParser()
500 cf.read(conf)502 cf.read(conf)
501 if cf.has_section("apt") and cf.has_option("apt", "frontend"):503 if cf.has_section("apt") and cf.has_option("apt", "frontend"):
502 frontend = cf.get("apt","frontend")504 frontend = cf.get("apt","frontend")
@@ -520,15 +522,16 @@
520 # mails on on errors, just exit here522 # mails on on errors, just exit here
521 if (res and523 if (res and
522 apt_pkg.config.find_b("Unattended-Upgrade::MailOnlyOnError", False)):524 apt_pkg.config.find_b("Unattended-Upgrade::MailOnlyOnError", False)):
523 return525 return
524 # Check if reboot-required flag is present526 # Check if reboot-required flag is present
525 logging.debug("Sending mail with '%s' to '%s'" % (logfile_dpkg, email))527 logging.debug("Sending mail with '%s' to '%s'" % (logfile_dpkg, email))
526 if os.path.isfile(REBOOT_REQUIRED_FILE):528 if os.path.isfile(REBOOT_REQUIRED_FILE):
527 subject = _("[reboot required] unattended-upgrades result for '%s'") % host()529 subject = _("[reboot required] unattended-upgrades result for '%s'") % host()
528 else:530 else:
529 subject = _("unattended-upgrades result for '%s'") % host()531 subject = _("unattended-upgrades result for '%s'") % host()
530 mail = subprocess.Popen([MAIL_BINARY, "-s", subject,532 mail = subprocess.Popen([MAIL_BINARY, "-s", subject, email],
531 email], stdin=subprocess.PIPE)533 stdin=subprocess.PIPE,
534 universal_newlines=True)
532 s = _("Unattended upgrade returned: %s\n\n") % res535 s = _("Unattended upgrade returned: %s\n\n") % res
533 if os.path.isfile(REBOOT_REQUIRED_FILE):536 if os.path.isfile(REBOOT_REQUIRED_FILE):
534 s += _("Warning: A reboot is required to complete this upgrade.\n\n")537 s += _("Warning: A reboot is required to complete this upgrade.\n\n")
@@ -542,7 +545,8 @@
542 s += "\n"545 s += "\n"
543 if os.path.exists(logfile_dpkg):546 if os.path.exists(logfile_dpkg):
544 s += _("Package installation log:")+"\n"547 s += _("Package installation log:")+"\n"
545 s += open(logfile_dpkg).read()548 with open(logfile_dpkg) as fp:
549 s += fp.read()
546 s += "\n\n"550 s += "\n\n"
547 s += _("Unattended-upgrades log:\n")551 s += _("Unattended-upgrades log:\n")
548 s += mem_log.getvalue()552 s += mem_log.getvalue()
@@ -569,7 +573,7 @@
569 old_stdout = 1573 old_stdout = 1
570 old_stderr = 2574 old_stderr = 2
571 else:575 else:
572 fd = os.open(logfile_dpkg, os.O_RDWR|os.O_CREAT, 0644)576 fd = os.open(logfile_dpkg, os.O_RDWR|os.O_CREAT, 0o644)
573 old_stdout = os.dup(1)577 old_stdout = os.dup(1)
574 old_stderr = os.dup(2)578 old_stderr = os.dup(2)
575 os.dup2(fd,1)579 os.dup2(fd,1)
@@ -580,7 +584,8 @@
580 # COMPAT with the mispelling584 # COMPAT with the mispelling
581 apt_pkg.config.find_b("Unattended-Upgrades::MinimalSteps", False) or585 apt_pkg.config.find_b("Unattended-Upgrades::MinimalSteps", False) or
582 apt_pkg.config.find_b("Unattended-Upgrade::MinimalSteps", False)):586 apt_pkg.config.find_b("Unattended-Upgrade::MinimalSteps", False)):
583 open("/var/run/unattended-upgrades.pid", "w").write("%s" % os.getpid())587 with open("/var/run/unattended-upgrades.pid", "w") as fp:
588 fp.write("%s" % os.getpid())
584 # try upgrade all "pkgs" in minimal steps589 # try upgrade all "pkgs" in minimal steps
585 pkg_install_success = upgrade_in_minimal_steps(590 pkg_install_success = upgrade_in_minimal_steps(
586 cache, [pkg.name for pkg in pkgs_to_upgrade], logfile_dpkg)591 cache, [pkg.name for pkg in pkgs_to_upgrade], logfile_dpkg)
@@ -677,7 +682,7 @@
677 lockfd = apt_pkg.get_lock(os.path.join(admindir, "lock"), False)682 lockfd = apt_pkg.get_lock(os.path.join(admindir, "lock"), False)
678 if lockfd > 0:683 if lockfd > 0:
679 logging.warning(_("Unclean dpkg state detected, trying to correct"))684 logging.warning(_("Unclean dpkg state detected, trying to correct"))
680 print _("Unclean dpkg state detected, trying to correct")685 print(_("Unclean dpkg state detected, trying to correct"))
681 env = copy.copy(os.environ)686 env = copy.copy(os.environ)
682 env["DEBIAN_FRONTEND"] = "noninteractive"687 env["DEBIAN_FRONTEND"] = "noninteractive"
683 try:688 try:
@@ -693,17 +698,17 @@
693 # check and get lock698 # check and get lock
694 try:699 try:
695 apt_pkg.pkgsystem_lock()700 apt_pkg.pkgsystem_lock()
696 except SystemError, e:701 except SystemError as e:
697 logging.error(_("Lock could not be acquired (another package "702 logging.error(_("Lock could not be acquired (another package "
698 "manager running?)"))703 "manager running?)"))
699 print _("Cache lock can not be acquired, exiting")704 print(_("Cache lock can not be acquired, exiting"))
700 sys.exit(1)705 sys.exit(1)
701706
702 # get a cache707 # get a cache
703 cache = UnattendedUpgradesCache(rootdir=rootdir, 708 cache = UnattendedUpgradesCache(rootdir=rootdir,
704 allowed_origins=allowed_origins)709 allowed_origins=allowed_origins)
705 if cache._depcache.broken_count > 0:710 if cache._depcache.broken_count > 0:
706 print _("Cache has broken packages, exiting")711 print(_("Cache has broken packages, exiting"))
707 logging.error(_("Cache has broken packages, exiting"))712 logging.error(_("Cache has broken packages, exiting"))
708 sys.exit(1)713 sys.exit(1)
709 # speed things up with latest apt714 # speed things up with latest apt
@@ -739,7 +744,7 @@
739 logging.debug("sanity check failed")744 logging.debug("sanity check failed")
740 rewind_cache(cache, pkgs_to_upgrade)745 rewind_cache(cache, pkgs_to_upgrade)
741 pkgs_kept_back.append(pkg.name)746 pkgs_kept_back.append(pkg.name)
742 except SystemError, e:747 except SystemError as e:
743 # can't upgrade748 # can't upgrade
744 logging.warning(_("package '%s' upgradable but fails to be marked for upgrade (%s)") % (pkg.name, e))749 logging.warning(_("package '%s' upgradable but fails to be marked for upgrade (%s)") % (pkg.name, e))
745 rewind_cache(cache, pkgs_to_upgrade)750 rewind_cache(cache, pkgs_to_upgrade)
@@ -761,7 +766,7 @@
761 pm = apt_pkg.PackageManager(cache._depcache)766 pm = apt_pkg.PackageManager(cache._depcache)
762 try:767 try:
763 pm.get_archives(fetcher,list,recs)768 pm.get_archives(fetcher,list,recs)
764 except SystemError, e:769 except SystemError as e:
765 logging.error(_("GetArchives() failed: '%s'") % e)770 logging.error(_("GetArchives() failed: '%s'") % e)
766 res = fetcher.run()771 res = fetcher.run()
767772
@@ -771,14 +776,14 @@
771 for item in fetcher.items:776 for item in fetcher.items:
772 logging.debug("%s" % item)777 logging.debug("%s" % item)
773 if item.status == item.STAT_ERROR:778 if item.status == item.STAT_ERROR:
774 print _("An error ocured: '%s'") % item.error_text779 print(_("An error ocured: '%s'") % item.error_text)
775 logging.error(_("An error ocured: '%s'") % item.error_text)780 logging.error(_("An error ocured: '%s'") % item.error_text)
776 if not item.complete:781 if not item.complete:
777 print _("The URI '%s' failed to download, aborting") % item.desc_uri782 print(_("The URI '%s' failed to download, aborting") % item.desc_uri)
778 logging.error(_("The URI '%s' failed to download, aborting") % item.desc_uri)783 logging.error(_("The URI '%s' failed to download, aborting") % item.desc_uri)
779 sys.exit(1)784 sys.exit(1)
780 if not os.path.exists(item.destfile):785 if not os.path.exists(item.destfile):
781 print _("Download finished, but file '%s' not there?!?" % item.destfile)786 print(_("Download finished, but file '%s' not there?!?" % item.destfile))
782 logging.error("Download finished, but file '%s' not there?!?" % item.destfile)787 logging.error("Download finished, but file '%s' not there?!?" % item.destfile)
783 sys.exit(1)788 sys.exit(1)
784 if not item.is_trusted:789 if not item.is_trusted:
@@ -792,7 +797,7 @@
792 # the cron mail (only if no summary mail is requested)797 # the cron mail (only if no summary mail is requested)
793 email = apt_pkg.config.find("Unattended-Upgrade::Mail", "")798 email = apt_pkg.config.find("Unattended-Upgrade::Mail", "")
794 if not email:799 if not email:
795 print _("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile)800 print(_("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile))
796 # log to the logfile801 # log to the logfile
797 logging.warning(_("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile))802 logging.warning(_("Package '%s' has conffile prompt and needs to be upgraded manually") % pkgname_from_deb(item.destfile))
798 blacklisted_pkgs.append(pkgname_from_deb(item.destfile))803 blacklisted_pkgs.append(pkgname_from_deb(item.destfile))
@@ -907,7 +912,7 @@
907 (options, args) = parser.parse_args()912 (options, args) = parser.parse_args()
908913
909 if os.getuid() != 0:914 if os.getuid() != 0:
910 print _("You need to be root to run this application")915 print(_("You need to be root to run this application"))
911 sys.exit(1)916 sys.exit(1)
912917
913 # nice & ionce918 # nice & ionce
914919
=== modified file 'unattended-upgrade-shutdown'
--- unattended-upgrade-shutdown 2012-04-26 11:40:46 +0000
+++ unattended-upgrade-shutdown 2012-06-25 20:04:38 +0000
@@ -1,4 +1,4 @@
1#!/usr/bin/python1#!/usr/bin/python3
2# Copyright (c) 2009 Canonical Ltd2# Copyright (c) 2009 Canonical Ltd
3#3#
4# AUTHOR:4# AUTHOR:
@@ -141,8 +141,8 @@
141 os.kill(pid, signal.SIGUSR1)141 os.kill(pid, signal.SIGUSR1)
142 # show log142 # show log
143 log_progress()143 log_progress()
144 time.sleep(5)144 time.sleep(5)
145 if (time.time() - start_time) > options.delay*60:145 if (time.time() - start_time) > options.delay*60:
146 logging.warning(_("Giving up on lockfile after %s delay") % options.delay)146 logging.warning(_("Giving up on lockfile after %s delay") % options.delay)
147 sys.exit(1)147 sys.exit(1)
148 148

Subscribers

People subscribed via source and target branches

to all changes: