Merge lp:~brian-murray/ubuntu-release-upgrader/remove-aufs into lp:ubuntu-release-upgrader

Proposed by Brian Murray
Status: Merged
Merged at revision: 3053
Proposed branch: lp:~brian-murray/ubuntu-release-upgrader/remove-aufs
Merge into: lp:ubuntu-release-upgrader
Diff against target: 480 lines (+9/-352)
8 files modified
DistUpgrade/DistUpgradeAufs.py (+0/-289)
DistUpgrade/DistUpgradeController.py (+0/-25)
DistUpgrade/DistUpgradeMain.py (+2/-5)
DistUpgrade/DistUpgradeView.py (+0/-15)
data/DistUpgrade.cfg (+0/-11)
data/do-release-upgrade.8 (+0/-3)
debian/changelog (+7/-0)
do-release-upgrade (+0/-4)
To merge this branch: bzr merge lp:~brian-murray/ubuntu-release-upgrader/remove-aufs
Reviewer Review Type Date Requested Status
Steve Langasek Approve
Review via email: mp+324216@code.launchpad.net

Description of the change

I spoke with Michael about the --sandbox option failing and he recommended just removing the aufs support so I did.

To post a comment you must log in.
Revision history for this message
Steve Langasek (vorlon) wrote :

LGTM, one minor comment inline.

review: Approve
Revision history for this message
Brian Murray (brian-murray) wrote :

Okay, I'll make that change.

3054. By Brian Murray

Remove error handling for AUFS option in environ.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'DistUpgrade/DistUpgradeAufs.py'
--- DistUpgrade/DistUpgradeAufs.py 2015-01-20 22:44:02 +0000
+++ DistUpgrade/DistUpgradeAufs.py 1970-01-01 00:00:00 +0000
@@ -1,289 +0,0 @@
1# DistUpgradeAufs.py
2#
3# Copyright (c) 2009-2012 Canonical
4#
5# Author: Michael Vogt <michael.vogt@ubuntu.com>
6#
7# This program is free software; you can redistribute it and/or
8# modify it under the terms of the GNU General Public License as
9# published by the Free Software Foundation; either version 2 of the
10# License, or (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program; if not, write to the Free Software
19# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20# USA
21
22import logging
23import os
24import subprocess
25import tempfile
26
27
28def aufsOptionsAndEnvironmentSetup(options, config):
29 """ setup the environment based on the config and options
30 It will use
31 config("Aufs","Enabled") - to show if its enabled
32 and
33 config("Aufs","RWDir") - for the writable overlay dir
34 """
35 logging.debug("aufsOptionsAndEnvironmentSetup()")
36 # enabled from the commandline (full overlay by default)
37 if options and options.useAufs:
38 logging.debug("enabling full overlay from commandline")
39 config.set("Aufs", "Enabled", "True")
40 config.set("Aufs", "EnableFullOverlay", "True")
41
42 # setup environment based on config
43 tmprw = tempfile.mkdtemp(prefix="upgrade-rw-")
44 aufs_rw_dir = config.getWithDefault("Aufs", "RWDir", tmprw)
45 logging.debug("using '%s' as aufs_rw_dir" % aufs_rw_dir)
46 os.environ["RELEASE_UPGRADE_AUFS_RWDIR"] = aufs_rw_dir
47 config.set("Aufs", "RWDir", aufs_rw_dir)
48 # now the chroot tmpdir
49 tmpchroot = tempfile.mkdtemp(prefix="upgrade-chroot-")
50 os.chmod(tmpchroot, 0o755)
51 aufs_chroot_dir = config.getWithDefault("Aufs", "ChrootDir", tmpchroot)
52 logging.debug("using '%s' as aufs chroot dir" % aufs_chroot_dir)
53
54 if config.getWithDefault("Aufs", "EnableFullOverlay", False):
55 logging.debug("enabling aufs full overlay (from config)")
56 config.set("Aufs", "Enabled", "True")
57 os.environ["RELEASE_UPGRADE_USE_AUFS_FULL_OVERLAY"] = "1"
58 if config.getWithDefault("Aufs", "EnableChrootOverlay", False):
59 logging.debug("enabling aufs chroot overlay")
60 config.set("Aufs", "Enabled", "True")
61 os.environ["RELEASE_UPGRADE_USE_AUFS_CHROOT"] = aufs_chroot_dir
62 if config.getWithDefault("Aufs", "EnableChrootRsync", False):
63 logging.debug("enable aufs chroot rsync back to real system")
64 os.environ["RELEASE_UPGRADE_RSYNC_AUFS_CHROOT"] = "1"
65
66
67def _bindMount(from_dir, to_dir, rbind=False):
68 " helper that bind mounts a given dir to a new place "
69 if not os.path.exists(to_dir):
70 os.makedirs(to_dir)
71 if rbind:
72 bind = "--rbind"
73 else:
74 bind = "--bind"
75 cmd = ["mount", bind, from_dir, to_dir]
76 logging.debug("cmd: %s" % cmd)
77 res = subprocess.call(cmd)
78 if res != 0:
79 # FIXME: revert already mounted stuff
80 logging.error(
81 "Failed to bind mount from '%s' to '%s'" % (from_dir, to_dir))
82 return False
83 return True
84
85
86def _aufsOverlayMount(target, rw_dir, chroot_dir="/"):
87 """
88 helper that takes a target dir and mounts a rw dir over it, e.g.
89 /var , /tmp/upgrade-rw
90 """
91 if not os.path.exists(rw_dir + target):
92 os.makedirs(rw_dir + target)
93 if not os.path.exists(chroot_dir + target):
94 os.makedirs(chroot_dir + target)
95 # FIXME: figure out when to use aufs and when to use overlayfs
96 use_overlayfs = False
97 if use_overlayfs:
98 cmd = ["mount",
99 "-t", "overlayfs",
100 "-o", "upperdir=%s,lowerdir=%s" % (rw_dir + target, target),
101 "none",
102 chroot_dir + target]
103 else:
104 cmd = ["mount",
105 "-t", "aufs",
106 "-o", "br:%s:%s=ro" % (rw_dir + target, target),
107 "none",
108 chroot_dir + target]
109 res = subprocess.call(cmd)
110 if res != 0:
111 # FIXME: revert already mounted stuff
112 logging.error("Failed to mount rw aufs overlay for '%s'" % target)
113 return False
114 logging.debug("cmd '%s' return '%s' " % (cmd, res))
115 return True
116
117
118def is_aufs_mount(dir):
119 " test if the given dir is already mounted with aufs overlay "
120 with open("/proc/mounts") as f:
121 for line in f:
122 (device, mountpoint, fstype, options, a, b) = line.split()
123 if device == "none" and fstype == "aufs" and mountpoint == dir:
124 return True
125 return False
126
127
128def is_submount(mountpoint, systemdirs):
129 " helper: check if the given mountpoint is a submount of a systemdir "
130 logging.debug("is_submount: %s %s" % (mountpoint, systemdirs))
131 for d in systemdirs:
132 if not d.endswith("/"):
133 d += "/"
134 if mountpoint.startswith(d):
135 return True
136 return False
137
138
139def is_real_fs(fs):
140 if fs.startswith("fuse"):
141 return False
142 if fs in ["rootfs", "tmpfs", "proc", "fusectrl", "aufs",
143 "devpts", "binfmt_misc", "sysfs"]:
144 return False
145 return True
146
147
148def doAufsChrootRsync(aufs_chroot_dir):
149 """
150 helper that rsyncs the changes in the aufs chroot back to the
151 real system
152 """
153 from .DistUpgradeMain import SYSTEM_DIRS
154 for d in SYSTEM_DIRS:
155 if not os.path.exists(d):
156 continue
157 # its important to have the "/" at the end of source
158 # and dest so that rsync knows what to do
159 cmd = ["rsync", "-aHAX", "--del", "-v", "--progress",
160 "/%s/%s/" % (aufs_chroot_dir, d),
161 "/%s/" % d]
162 logging.debug("running: '%s'" % cmd)
163 ret = subprocess.call(cmd)
164 logging.debug("rsync back result for %s: %i" % (d, ret))
165 return True
166
167
168def doAufsChroot(aufs_rw_dir, aufs_chroot_dir):
169 " helper that sets the chroot up and does chroot() into it "
170 if not setupAufsChroot(aufs_rw_dir, aufs_chroot_dir):
171 return False
172 os.chroot(aufs_chroot_dir)
173 os.chdir("/")
174 return True
175
176
177def setupAufsChroot(rw_dir, chroot_dir):
178 " setup aufs chroot that is based on / but with a writable overlay "
179 # with the chroot aufs we can just rsync the changes back
180 # from the chroot dir to the real dirs
181 #
182 # (if we run rsync with --backup --backup-dir we could even
183 # create something vaguely rollbackable
184
185 # get the mount points before the aufs buisiness starts
186 with open("/proc/mounts") as f:
187 mounts = f.read()
188 from .DistUpgradeMain import SYSTEM_DIRS
189 systemdirs = SYSTEM_DIRS
190
191 # aufs mount or bind mount required dirs
192 for d in os.listdir("/"):
193 d = os.path.join("/", d)
194 if os.path.isdir(d):
195 if d in systemdirs:
196 logging.debug("bind mounting %s" % d)
197 if not _aufsOverlayMount(d, rw_dir, chroot_dir):
198 return False
199 else:
200 logging.debug("overlay mounting %s" % d)
201 if not _bindMount(d, chroot_dir + d, rbind=True):
202 return False
203
204 # create binds for the systemdirs
205 #needs_bind_mount = set()
206 for line in mounts.split("\n"):
207 line = line.strip()
208 if not line:
209 continue
210 (device, mountpoint, fstype, options, a, b) = line.split()
211 if (fstype != "aufs" and
212 not is_real_fs(fstype) and
213 is_submount(mountpoint, systemdirs)):
214 logging.debug("found %s that needs bind mount", mountpoint)
215 if not _bindMount(mountpoint, chroot_dir + mountpoint):
216 return False
217 return True
218
219
220def setupAufs(rw_dir):
221 " setup aufs overlay over the rootfs "
222 # * we need to find a way to tell all the existing daemon
223 # to look into the new namespace. so probably something
224 # like a reboot is required and some hackery in initramfs-tools
225 # to ensure that we boot into a overlay ready system
226 # * this is much less of a issue with the aufsChroot code
227 logging.debug("setupAufs")
228 if not os.path.exists("/proc/mounts"):
229 logging.debug("no /proc/mounts, can not do aufs overlay")
230 return False
231
232 from .DistUpgradeMain import SYSTEM_DIRS
233 systemdirs = SYSTEM_DIRS
234 # verify that there are no submounts of a systemdir and collect
235 # the stuff that needs bind mounting (because a aufs does not
236 # include sub mounts)
237 needs_bind_mount = set()
238 needs_bind_mount.add("/var/cache/apt/archives")
239 with open("/proc/mounts") as f:
240 for line in f:
241 (device, mountpoint, fstype, options, a, b) = line.split()
242 if is_real_fs(fstype) and is_submount(mountpoint, systemdirs):
243 logging.warning("mountpoint %s submount of systemdir" %
244 mountpoint)
245 return False
246 if (fstype != "aufs" and
247 not is_real_fs(fstype) and
248 is_submount(mountpoint, systemdirs)):
249 logging.debug("found %s that needs bind mount", mountpoint)
250 needs_bind_mount.add(mountpoint)
251
252 # aufs mounts do not support stacked filesystems, so
253 # if we mount /var we will loose the tmpfs stuff
254 # first bind mount varun and varlock into the tmpfs
255 for d in needs_bind_mount:
256 if not _bindMount(d, rw_dir + "/needs_bind_mount/" + d):
257 return False
258 # setup writable overlay into /tmp/upgrade-rw so that all
259 # changes are written there instead of the real fs
260 for d in systemdirs:
261 if not is_aufs_mount(d):
262 if not _aufsOverlayMount(d, rw_dir):
263 return False
264 # now bind back the tempfs to the original location
265 for d in needs_bind_mount:
266 if not _bindMount(rw_dir + "/needs_bind_mount/" + d, d):
267 return False
268
269 # The below information is only of historical relevance:
270 # now what we *could* do to apply the changes is to
271 # mount -o bind / /orig
272 # (bind is important, *not* rbind that includes submounts)
273 #
274 # This will give us the original "/" without the
275 # aufs rw overlay - *BUT* only if "/" is all on one parition
276 #
277 # then apply the diff (including the whiteouts) to /orig
278 # e.g. by "rsync -av /tmp/upgrade-rw /orig"
279 # "script that search for whiteouts and removes them"
280 # (whiteout files start with .wh.$name
281 # whiteout dirs with .wh..? - check with aufs man page)
282 return True
283
284
285if __name__ == "__main__":
286 logging.basicConfig(level=logging.DEBUG)
287 #print(setupAufs("/tmp/upgrade-rw"))
288 print(setupAufsChroot("/tmp/upgrade-chroot-rw",
289 "/tmp/upgrade-chroot"))
2900
=== modified file 'DistUpgrade/DistUpgradeController.py'
--- DistUpgrade/DistUpgradeController.py 2016-08-10 15:09:46 +0000
+++ DistUpgrade/DistUpgradeController.py 2017-05-18 17:34:09 +0000
@@ -57,7 +57,6 @@
57from .DistUpgradeConfigParser import DistUpgradeConfig57from .DistUpgradeConfigParser import DistUpgradeConfig
58from .DistUpgradeQuirks import DistUpgradeQuirks58from .DistUpgradeQuirks import DistUpgradeQuirks
59from .DistUpgradeAptCdrom import AptCdrom59from .DistUpgradeAptCdrom import AptCdrom
60from .DistUpgradeAufs import setupAufs, aufsOptionsAndEnvironmentSetup
6160
62# workaround broken relative import in python-apt (LP: #871007), we61# workaround broken relative import in python-apt (LP: #871007), we
63# want the local version of distinfo.py from oneiric, but because of62# want the local version of distinfo.py from oneiric, but because of
@@ -138,9 +137,6 @@
138 self.config.add_section("Options")137 self.config.add_section("Options")
139 self.config.set("Options","withNetwork", str(self.useNetwork))138 self.config.set("Options","withNetwork", str(self.useNetwork))
140139
141 # aufs stuff
142 aufsOptionsAndEnvironmentSetup(self.options, self.config)
143
144 # some constants here140 # some constants here
145 self.fromDist = self.config.get("Sources","From")141 self.fromDist = self.config.get("Sources","From")
146 self.toDist = self.config.get("Sources","To")142 self.toDist = self.config.get("Sources","To")
@@ -399,27 +395,6 @@
399 "supported with this tool." % (release, self.toDist)))395 "supported with this tool." % (release, self.toDist)))
400 sys.exit(1)396 sys.exit(1)
401397
402 # setup aufs
403 if self.config.getWithDefault("Aufs", "EnableFullOverlay", False):
404 aufs_rw_dir = self.config.get("Aufs","RWDir")
405 if not setupAufs(aufs_rw_dir):
406 logging.error("aufs setup failed")
407 self._view.error(_("Sandbox setup failed"),
408 _("It was not possible to create the sandbox "
409 "environment."))
410 return False
411
412 # all good, tell the user about the sandbox mode
413 logging.info("running in aufs overlay mode")
414 self._view.information(_("Sandbox mode"),
415 _("This upgrade is running in sandbox "
416 "(test) mode. All changes are written "
417 "to '%s' and will be lost on the next "
418 "reboot.\n\n"
419 "*No* changes written to a system directory "
420 "from now until the next reboot are "
421 "permanent.") % aufs_rw_dir)
422
423 # setup backports (if we have them)398 # setup backports (if we have them)
424 if self.options and self.options.havePrerequists:399 if self.options and self.options.havePrerequists:
425 backportsdir = os.getcwd()+"/backports"400 backportsdir = os.getcwd()+"/backports"
426401
=== modified file 'DistUpgrade/DistUpgradeMain.py'
--- DistUpgrade/DistUpgradeMain.py 2017-05-03 10:03:08 +0000
+++ DistUpgrade/DistUpgradeMain.py 2017-05-18 17:34:09 +0000
@@ -33,8 +33,8 @@
33from optparse import OptionParser33from optparse import OptionParser
34from gettext import gettext as _34from gettext import gettext as _
3535
36# dirs that the packages will touch, this is needed for AUFS/overlayfs36# dirs that the packages will touch, this is needed for the sanity check
37# and also for the sanity check before the upgrade37# before the upgrade
38SYSTEM_DIRS = ["/bin",38SYSTEM_DIRS = ["/bin",
39 "/boot",39 "/boot",
40 "/etc",40 "/etc",
@@ -54,9 +54,6 @@
54def do_commandline():54def do_commandline():
55 " setup option parser and parse the commandline "55 " setup option parser and parse the commandline "
56 parser = OptionParser()56 parser = OptionParser()
57 parser.add_option("-s", "--sandbox", dest="useAufs", default=False,
58 action="store_true",
59 help=_("Sandbox upgrade using aufs"))
60 parser.add_option("-c", "--cdrom", dest="cdromPath", default=None,57 parser.add_option("-c", "--cdrom", dest="cdromPath", default=None,
61 help=_("Use the given path to search for a cdrom with upgradable packages"))58 help=_("Use the given path to search for a cdrom with upgradable packages"))
62 parser.add_option("--have-prerequists", dest="havePrerequists",59 parser.add_option("--have-prerequists", dest="havePrerequists",
6360
=== modified file 'DistUpgrade/DistUpgradeView.py'
--- DistUpgrade/DistUpgradeView.py 2016-02-08 22:40:04 +0000
+++ DistUpgrade/DistUpgradeView.py 2017-05-18 17:34:09 +0000
@@ -30,7 +30,6 @@
30import signal30import signal
31import select31import select
3232
33from .DistUpgradeAufs import doAufsChroot, doAufsChrootRsync
34from .DistUpgradeApport import apport_pkgfailure33from .DistUpgradeApport import apport_pkgfailure
3534
3635
@@ -212,12 +211,6 @@
212 def run(self, pm):211 def run(self, pm):
213 pid = self.fork()212 pid = self.fork()
214 if pid == 0:213 if pid == 0:
215 # check if we need to setup/enable the aufs chroot stuff
216 if "RELEASE_UPGRADE_USE_AUFS_CHROOT" in os.environ:
217 if not doAufsChroot(os.environ["RELEASE_UPGRADE_AUFS_RWDIR"],
218 os.environ["RELEASE_UPGRADE_USE_AUFS_CHROOT"]):
219 print("ERROR: failed to setup aufs chroot overlay")
220 os._exit(1)
221 # child, ignore sigpipe, there are broken scripts out there214 # child, ignore sigpipe, there are broken scripts out there
222 # like etckeeper (LP: #283642)215 # like etckeeper (LP: #283642)
223 signal.signal(signal.SIGPIPE,signal.SIG_IGN) 216 signal.signal(signal.SIGPIPE,signal.SIG_IGN)
@@ -232,14 +225,6 @@
232 os._exit(res)225 os._exit(res)
233 self.child_pid = pid226 self.child_pid = pid
234 res = os.WEXITSTATUS(self.wait_child())227 res = os.WEXITSTATUS(self.wait_child())
235 # check if we want to sync the changes back, *only* do that
236 # if res is positive
237 if (res == 0 and
238 "RELEASE_UPGRADE_RSYNC_AUFS_CHROOT" in os.environ):
239 logging.info("doing rsync commit of the update")
240 if not doAufsChrootRsync(os.environ["RELEASE_UPGRADE_USE_AUFS_CHROOT"]):
241 logging.error("FATAL ERROR: doAufsChrootRsync() returned FALSE")
242 return pm.RESULT_FAILED
243 return res228 return res
244 229
245 def error(self, pkg, errormsg):230 def error(self, pkg, errormsg):
246231
=== modified file 'data/DistUpgrade.cfg'
--- data/DistUpgrade.cfg 2017-04-24 21:15:03 +0000
+++ data/DistUpgrade.cfg 2017-05-18 17:34:09 +0000
@@ -128,17 +128,6 @@
128;SourcesList-ia64=prerequists-sources.ports.list128;SourcesList-ia64=prerequists-sources.ports.list
129;SourcesList-hppa=prerequists-sources.ports.list129;SourcesList-hppa=prerequists-sources.ports.list
130130
131[Aufs]
132; this is a xor option, either full or chroot overlay
133;EnableFullOverlay=yes
134;EnableChrootOverlay=yes
135; sync changes from the chroot back to the real system
136;EnableChrootRsync=yes
137; what chroot dir to use
138;ChrootDir=/tmp/upgrade-chroot
139; the RW dir to use (either for full overlay or chroot overlay)
140;RWDir=/tmp/upgrade-rw
141
142[Network]131[Network]
143MaxRetries=3132MaxRetries=3
144133
145134
=== modified file 'data/do-release-upgrade.8'
--- data/do-release-upgrade.8 2012-06-13 11:47:22 +0000
+++ data/do-release-upgrade.8 2017-05-18 17:34:09 +0000
@@ -28,8 +28,5 @@
28.TP 28.TP
29\fB\-f\fR FRONTEND, \fB\-\-frontend\fR=\fIFRONTEND\fR29\fB\-f\fR FRONTEND, \fB\-\-frontend\fR=\fIFRONTEND\fR
30Run the specified frontend30Run the specified frontend
31.TP
32\fB\-s\fR, \fB\-\-sandbox\fR
33Test upgrade with a sandbox aufs overlay
34.SH "SEE ALSO"31.SH "SEE ALSO"
35\fBupdate\-manager\fR(8), \fBapt\-get\fR(8)32\fBupdate\-manager\fR(8), \fBapt\-get\fR(8)
3633
=== modified file 'debian/changelog'
--- debian/changelog 2017-05-03 16:12:01 +0000
+++ debian/changelog 2017-05-18 17:34:09 +0000
@@ -1,3 +1,10 @@
1ubuntu-release-upgrader (1:17.10.3) UNRELEASED; urgency=medium
2
3 * Remove --sandbox (aufs support) as it has been broken for some time and
4 was rather unused. (LP: #1605259)
5
6 -- Brian Murray <brian@ubuntu.com> Wed, 17 May 2017 14:38:24 -0700
7
1ubuntu-release-upgrader (1:17.10.2) artful; urgency=medium8ubuntu-release-upgrader (1:17.10.2) artful; urgency=medium
29
3 [ Balint Reczey ]10 [ Balint Reczey ]
411
=== modified file 'do-release-upgrade'
--- do-release-upgrade 2015-04-16 23:00:33 +0000
+++ do-release-upgrade 2017-05-18 17:34:09 +0000
@@ -96,8 +96,6 @@
96 parser.add_option ("-f", "--frontend", default="DistUpgradeViewText",96 parser.add_option ("-f", "--frontend", default="DistUpgradeViewText",
97 dest="frontend", 97 dest="frontend",
98 help=_("Run the specified frontend"))98 help=_("Run the specified frontend"))
99 parser.add_option ("-s","--sandbox", action="store_true", default=False,
100 help=_("Test upgrade with a sandbox aufs overlay"))
101 parser.add_option ("-c", "--check-dist-upgrade-only", action="store_true",99 parser.add_option ("-c", "--check-dist-upgrade-only", action="store_true",
102 default=check_only,100 default=check_only,
103 help=_("Check only if a new distribution release is "101 help=_("Check only if a new distribution release is "
@@ -158,8 +156,6 @@
158 fetcher.run_options += ["--mode=%s" % options.mode,156 fetcher.run_options += ["--mode=%s" % options.mode,
159 "--frontend=%s" % options.frontend,157 "--frontend=%s" % options.frontend,
160 ]158 ]
161 if options.sandbox:
162 fetcher.run_options.append("--sandbox")
163 if options.devel_release:159 if options.devel_release:
164 fetcher.run_options.append("--devel-release")160 fetcher.run_options.append("--devel-release")
165 fetcher.run()161 fetcher.run()

Subscribers

People subscribed via source and target branches