Merge lp:~rbalint/livecd-rootfs/minimize-unminimize-xenial into lp:~ubuntu-core-dev/livecd-rootfs/xenial-proposed

Proposed by Balint Reczey
Status: Merged
Merged at revision: 1425
Proposed branch: lp:~rbalint/livecd-rootfs/minimize-unminimize-xenial
Merge into: lp:~ubuntu-core-dev/livecd-rootfs/xenial-proposed
Diff against target: 420 lines (+192/-13)
11 files modified
debian/changelog (+26/-1)
debian/control (+1/-1)
debian/tests/control (+4/-0)
debian/tests/default-bootstraps (+1/-0)
debian/tests/minimized (+3/-0)
live-build/auto/build (+107/-2)
live-build/auto/config (+19/-8)
live-build/ubuntu-cpc/functions (+5/-0)
live-build/ubuntu-cpc/hooks/032-disk-image.binary (+11/-0)
live-build/ubuntu-cpc/hooks/033-disk-image-uefi.binary (+10/-0)
live-build/ubuntu-cpc/hooks/999-cpc-fixes.chroot (+5/-1)
To merge this branch: bzr merge lp:~rbalint/livecd-rootfs/minimize-unminimize-xenial
Reviewer Review Type Date Requested Status
Steve Langasek Pending
Review via email: mp+331745@code.launchpad.net

Description of the change

Image minimization for Xenial

To post a comment you must log in.
Revision history for this message
Balint Reczey (rbalint) wrote :
1425. By Steve Langasek

Merge lp:~rbalint/livecd-rootfs/minimize-unminimize-xenial

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2017-09-26 05:10:15 +0000
3+++ debian/changelog 2017-10-03 22:07:43 +0000
4@@ -12,11 +12,36 @@
5 downstream.
6 * Also nuke the sleep / udevadm settle calls in the process, which should
7 never be required and slow down the builds.
8+ * Begin adding support for a project-independent 'minimized' subproject,
9+ which (ironically) omits ubuntu-minimal in favor of using only the minbase
10+ package set.
11+ * Export the subproject into config/chroot and config/binary, so that this
12+ information is available to per-project hooks that need to be
13+ subproject-aware (e.g., to skip steps when SUBPROJECT=minimized)
14+ * Make the 999-cpc-fixes.chroot subproject-aware, so we don't try to
15+ locale-gen
16+ * In a cloud environment, we can rely on the kernel being able to boot the
17+ root filesystem directly, without an initramfs; enable this when building
18+ minimized.
19+ * If we're using SUBPROJECT=minimized, and tzdata is not installed, remove
20+ files that have been left behind. This is a workaround for a bug that
21+ should be fixed in tzdata.
22+ * Fix a reference to an undefined variable in a script that's set -u.
23+ * Use /bin/sh, not /bin/bash, for autopkgtest.
24
25 [ Balint Reczey ]
26 * Mount using --make-rslave to ensure safe unmounts for rbind mounts
27+ * Drop man pages and most of the documentation from minimized images
28+ /usr/share/doc/*/copyright and changelog.Debian.gz files are still kept
29+ * Add unminimize script for reverting minimization on running system
30+ * Install ubuntu-minimal while unminimizing the system
31+ * Bump needed live-build version which can build images without initrd
32+ * Mention unminimize script in motd
33+ * Warn users that unminimize may fail reinstalling packages
34+ * Run autopkgtest for SUBPROJECT=minimized
35+ * When SUBPROJECT environment variable is not set assume it to be ""
36
37- -- Victor Tapia <victor.tapia@canonical.com> Tue, 19 Sep 2017 10:55:11 +0200
38+ -- Balint Reczey <rbalint@ubuntu.com> Tue, 03 Oct 2017 17:35:04 +0200
39
40 livecd-rootfs (2.408.18) xenial; urgency=medium
41
42
43=== modified file 'debian/control'
44--- debian/control 2017-02-09 06:57:39 +0000
45+++ debian/control 2017-10-03 22:07:43 +0000
46@@ -8,7 +8,7 @@
47
48 Package: livecd-rootfs
49 Architecture: any
50-Depends: ${misc:Depends}, debootstrap, rsync, python-minimal | python, procps, squashfs-tools (>= 1:3.3-1), grep-dctrl, lsb-release, lzma, e2fsprogs, germinate (>= 1.25.1), apt-utils, gnupg, live-build (>= 3.0~a57-1ubuntu12~), android-tools-fsutils [armhf], python3-software-properties
51+Depends: ${misc:Depends}, debootstrap, rsync, python-minimal | python, procps, squashfs-tools (>= 1:3.3-1), grep-dctrl, lsb-release, lzma, e2fsprogs, germinate (>= 1.25.1), apt-utils, gnupg, live-build (>= 3.0~a57-1ubuntu25.5~), android-tools-fsutils [armhf], python3-software-properties
52 Suggests: partimage
53 Breaks: ubuntu-defaults-builder (<< 0.32)
54 Description: construction script for the livecd rootfs
55
56=== modified file 'debian/tests/control'
57--- debian/tests/control 2017-05-12 19:20:22 +0000
58+++ debian/tests/control 2017-10-03 22:07:43 +0000
59@@ -1,3 +1,7 @@
60 Tests: default-bootstraps
61 Depends: @, lsb-release
62 Restrictions: needs-root isolation-machine
63+
64+Tests: minimized
65+Depends: @, lsb-release
66+Restrictions: needs-root isolation-machine
67
68=== modified file 'debian/tests/default-bootstraps'
69--- debian/tests/default-bootstraps 2017-05-12 19:20:22 +0000
70+++ debian/tests/default-bootstraps 2017-10-03 22:07:43 +0000
71@@ -30,6 +30,7 @@
72 ubuntu-budgie-live::
73 ubuntu-core:system-image:ubuntu-core
74 ubuntu-cpc::ubuntu-cpc
75+ ubuntu-cpc:minimized:ubuntu-cpc
76 ubuntu-desktop-next:system-image:ubuntu-desktop-next
77 ubuntu-desktop-next::ubuntu-desktop-next
78 ubuntu-dvd::
79
80=== added file 'debian/tests/minimized'
81--- debian/tests/minimized 1970-01-01 00:00:00 +0000
82+++ debian/tests/minimized 2017-10-03 22:07:43 +0000
83@@ -0,0 +1,3 @@
84+#!/bin/sh
85+
86+env SELECTED_TRIPLETS=ubuntu-cpc:minimized:ubuntu-cpc debian/tests/default-bootstraps
87
88=== modified file 'live-build/auto/build'
89--- live-build/auto/build 2017-04-04 15:28:52 +0000
90+++ live-build/auto/build 2017-10-03 22:07:43 +0000
91@@ -31,6 +31,111 @@
92
93 lb bootstrap "$@"
94
95+ if [ "${SUBPROJECT:-}" = minimized ] \
96+ && ! Chroot chroot dpkg -l tzdata 2>&1 |grep -q ^ii; then
97+ # workaround for tzdata purge not removing these files
98+ rm -f chroot/etc/localtime chroot/etc/timezone
99+ fi
100+
101+ if [ "${SUBPROJECT:-}" = minimized ]; then
102+ # set up dpkg filters to skip installing docs on minimizedd system
103+ mkdir -p chroot/etc/dpkg/dpkg.cfg.d
104+ cat > chroot/etc/dpkg/dpkg.cfg.d/excludes <<EOF
105+# Drop all man pages
106+path-exclude=/usr/share/man/*
107+
108+# Drop all documentation ...
109+path-exclude=/usr/share/doc/*
110+
111+# ... except copyright files ...
112+path-include=/usr/share/doc/*/copyright
113+
114+# ... and Debian changelogs
115+path-include=/usr/share/doc/*/changelog.Debian.*
116+EOF
117+
118+ # Remove docs installed by bootstrap
119+ Chroot chroot dpkg-query -f '${binary:Package}\n' -W | Chroot chroot xargs apt-get install --reinstall
120+
121+ # Add unminimizer script which restores default image behavior
122+ mkdir -p chroot/usr/local/sbin
123+ cat > chroot/usr/local/sbin/unminimize <<'EOF'
124+#!/bin/sh
125+
126+set -e
127+
128+echo "This system was optimized for smaller footprint by reducing the available"
129+echo "installed documentation, removal of rarely used tools, and by other means."
130+echo ""
131+echo "This script reverts part of the optimization and makes documentation and"
132+echo "tools available again to match the familiar Ubuntu minimial system."
133+echo ""
134+echo "Be warned that reinstallation of packages may fail due to changes to the"
135+echo "system configuration, due to installation of 3rd party packages, or for"
136+echo "other reasons."
137+read -p "Would you like to continue? [y/N]" REPLY
138+echo # (optional) move to a new line
139+if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]
140+then
141+ exit 1
142+fi
143+
144+if [ -f /etc/dpkg/dpkg.cfg.d/excludes ] || [ -f /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp ]; then
145+ echo "Re-enabling installation of all documentation in dpkg..."
146+ if [ -f /etc/dpkg/dpkg.cfg.d/excludes ]; then
147+ mv /etc/dpkg/dpkg.cfg.d/excludes /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp
148+ fi
149+ echo "Updating package list and upgrading packages..."
150+ apt-get update
151+ # apt-get upgrade asks for confirmation before upgrading packages to let the user stop here
152+ apt-get upgrade
153+ echo "Restoring system documentation..."
154+ echo "Reinstalling packages with files in /usr/share/man/ ..."
155+ # Reinstallation takes place in two steps because a single dpkg --verified
156+ # command generates very long parameter list for "xargs dpkg -S" and may go
157+ # over ARG_MAX. Since many packages have man pages the second download
158+ # handles a much smaller amount of packages.
159+ dpkg -S /usr/share/man/ |sed 's|, |\n|g;s|: [^:]*$||' | DEBIAN_FRONTEND=noninteractive xargs apt-get install --reinstall -y
160+ echo "Reinstalling packages with system documentation in /usr/share/doc/ .."
161+ # This step processes the packages which still have missing documentation
162+ dpkg --verify --verify-format rpm | awk '/..5...... \/usr\/share\/doc/ {print $2}' | sed 's|/[^/]*$||' | sort |uniq \
163+ | xargs dpkg -S | sed 's|, |\n|g;s|: [^:]*$||' | uniq | DEBIAN_FRONTEND=noninteractive xargs apt-get install --reinstall -y
164+ if dpkg --verify --verify-format rpm | awk '/..5...... \/usr\/share\/doc/ {exit 1}'; then
165+ echo "Documentation has been restored successfully."
166+ rm /etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp
167+ else
168+ echo "There are still files missing from /usr/share/doc/:"
169+ dpkg --verify --verify-format rpm | awk '/..5...... \/usr\/share\/doc/ {print " " $2}'
170+ echo "You may want to try running this script again or you can remove"
171+ echo "/etc/dpkg/dpkg.cfg.d/excludes.dpkg-tmp and restore the files manually."
172+ fi
173+fi
174+
175+if ! dpkg-query --show --showformat='${db:Status-Status}\n' ubuntu-minimal 2> /dev/null | grep -q '^installed$'; then
176+ echo "Installing ubuntu-minimal package to provide the familiar Ubuntu minimal system..."
177+ DEBIAN_FRONTEND=noninteractive apt-get install -y ubuntu-minimal
178+fi
179+
180+# unminimization succeeded, there is no need to mention it in motd
181+rm -f /etc/update-motd.d/60-unminimize
182+
183+EOF
184+ chmod +x chroot/usr/local/sbin/unminimize
185+ fi
186+
187+ # inform users about the unminimize script
188+ cat > "chroot/etc/update-motd.d/60-unminimize" << EOF
189+#!/bin/sh
190+#
191+# This file is not managed by a package. If you no longer want to
192+# see this message you can safely remove the file.
193+echo ""
194+echo "This system does not provide part of the tools and documentation"
195+echo "which are available on standard Ubuntu systems."
196+echo "To make them available please run the "unminimize" command."
197+EOF
198+
199+ chmod +x chroot/etc/update-motd.d/60-unminimize
200 Chroot chroot "dpkg-divert --quiet --add \
201 --divert /usr/sbin/update-initramfs.REAL --rename \
202 /usr/sbin/update-initramfs"
203@@ -249,7 +354,7 @@
204 cp -a binary-tar.tar.gz "$PREFIX.rootfs.tar.gz"
205 fi
206
207-if [ "$PROJECT:$SUBPROJECT" = "ubuntu-core:system-image" ]; then
208+if [ "$PROJECT:${SUBPROJECT:-}" = "ubuntu-core:system-image" ]; then
209 if [ -e "binary/$INITFS/filesystem.dir" ]; then
210 rootfs="binary/$INITFS/filesystem.dir"
211
212@@ -297,7 +402,7 @@
213 # ubuntu-core and ubuntu-desktop-next splits kernel stuff into a "device" tarball so
214 # at this point we reset it to "none" as all the work to extract it was done already
215 # in a binary hook
216-case $PROJECT:$SUBPROJECT in
217+case $PROJECT:${SUBPROJECT:-} in
218 ubuntu-core:system-image|ubuntu-desktop-next:system-image)
219
220 # create device tarball (for snappy only atm)
221
222=== modified file 'live-build/auto/config'
223--- live-build/auto/config 2017-07-12 22:34:36 +0000
224+++ live-build/auto/config 2017-10-03 22:07:43 +0000
225@@ -117,7 +117,7 @@
226 ext2|ext3|ext4)
227 OPTS="${OPTS:+$OPTS }--initramfs none --chroot-filesystem $IMAGEFORMAT"
228 PREINSTALLED=true
229- case $SUBPROJECT in
230+ case ${SUBPROJECT:-} in
231 wubi)
232 add_package install lupin-support
233 COMPONENTS='main restricted universe multiverse'
234@@ -196,6 +196,10 @@
235 HWE_KERNEL_FLAVOUR="generic-hwe-16.04"
236 HWE_SIGNED_KERNEL_PACKAGE="linux-signed-$HWE_KERNEL_FLAVOUR"
237
238+if [ "${SUBPROJECT:-}" = minimized ]; then
239+ OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal"
240+fi
241+
242 case $PROJECT in
243 ubuntu|ubuntu-dvd)
244 HWE_BUILD="yes"
245@@ -223,7 +227,7 @@
246 # CDIMAGE_PREINSTALLED is not passed from build.py
247 # and PREINSTALLED means something different. So
248 # we use SUBPROJECT to pass on the information
249- if [ "$SUBPROJECT" = "system-image" ]; then
250+ if [ "${SUBPROJECT:-}" = "system-image" ]; then
251 OPTS="${OPTS:+$OPTS }--linux-packages=linux-image"
252 fi
253 ;;
254@@ -477,7 +481,7 @@
255 # SUBPROJECT, but it's a handy thing that launchpad-buildd
256 # already passes through to us that we weren't otherwise
257 # using here.
258- case $SUBPROJECT in
259+ case ${SUBPROJECT:-} in
260 ubuntu-rtm/dogfood)
261 MIRROR=http://derived-archive.dogfood.content.paddev.net/ubuntu-rtm/
262 OPTS="${OPTS:+$OPTS }--apt-secure false"
263@@ -495,8 +499,13 @@
264 ;;
265
266 ubuntu-cpc)
267- add_task install minimal standard cloud-image
268- add_package install ubuntu-minimal
269+ if [ "${SUBPROJECT:-}" = minimized ]; then
270+ add_task install cloud-image
271+ add_package install sudo
272+ else
273+ add_task install minimal standard cloud-image
274+ add_package install ubuntu-minimal
275+ fi
276
277 BINARY_REMOVE_LINUX=false
278 OPTS="${OPTS:+$OPTS }--initramfs=none"
279@@ -630,7 +639,7 @@
280 ;;
281 esac
282
283-case $SUBPROJECT in
284+case ${SUBPROJECT:-} in
285 wubi)
286 add_binary_hook build-wubildr
287 ;;
288@@ -656,8 +665,10 @@
289 "$@"
290
291 echo "LB_CHROOT_HOOKS=\"$CHROOT_HOOKS\"" >> config/chroot
292+echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/chroot
293 echo "LB_BINARY_HOOKS=\"$BINARY_HOOKS\"" >> config/binary
294 echo "BUILDSTAMP=\"$NOW\"" >> config/binary
295+echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/binary
296
297 case $ARCH+$SUBARCH in
298 armhf+raspi2)
299@@ -772,7 +783,7 @@
300 config/archives/proposed.list.binary
301 fi
302
303-case $PROJECT:$SUBPROJECT in
304+case $PROJECT:${SUBPROJECT:-} in
305 *-dvd:*)
306 . config/bootstrap
307
308@@ -858,7 +869,7 @@
309 fi
310 fi
311
312-case $SUBPROJECT in
313+case ${SUBPROJECT:-} in
314 ubuntu-rtm|ubuntu-rtm/*)
315 # debootstrap doesn't know about ubuntu-rtm series directly. Rather
316 # than having to teach it, we employ a few hacks to make it use the
317
318=== modified file 'live-build/ubuntu-cpc/functions'
319--- live-build/ubuntu-cpc/functions 2017-09-26 05:10:15 +0000
320+++ live-build/ubuntu-cpc/functions 2017-10-03 22:07:43 +0000
321@@ -273,6 +273,11 @@
322 # Instead, we want grub to use the cloudimg-rootfs labelled disk
323 CHROOT_ROOT="$1"
324
325+ # If boot by partuuid has been requested, don't override.
326+ if [ -f $CHROOT_ROOT/etc/default/grub.d/40-partuuid ] && \
327+ grep -q ^GRUB_FORCE_PARTUUID= $CHROOT_ROOT/etc/default/grub.d/40-partuuid; then
328+ return 0
329+ fi
330 sed -i -e "s,root=[^ ]\+,root=LABEL=cloudimg-rootfs," \
331 "$CHROOT_ROOT/boot/grub/grub.cfg"
332 }
333
334=== modified file 'live-build/ubuntu-cpc/hooks/032-disk-image.binary'
335--- live-build/ubuntu-cpc/hooks/032-disk-image.binary 2017-05-12 19:20:22 +0000
336+++ live-build/ubuntu-cpc/hooks/032-disk-image.binary 2017-10-03 22:07:43 +0000
337@@ -2,6 +2,8 @@
338
339 . config/functions
340
341+. config/binary
342+
343 BOOTPART_START=
344 BOOTPART_END=
345 BOOT_MOUNTPOINT=
346@@ -64,6 +66,8 @@
347
348 mount_image "${disk_image}" "$ROOTPART"
349
350+partuuid=$(blkid -s PARTUUID -o value "$rootfs_dev_mapper")
351+
352 # Copy the chroot in to the disk
353 make_ext4_partition "${rootfs_dev_mapper}"
354 mkdir mountpoint
355@@ -111,6 +115,13 @@
356 ${loop_device}
357
358 rm mountpoint/tmp/device.map
359+
360+ if [ "${SUBPROJECT:-}" = minimized ] && [ -n "$partuuid" ]; then
361+ echo "partuuid found for root device; forcing it in Grub"
362+ mkdir -p mountpoint/etc/default/grub.d
363+ echo "GRUB_FORCE_PARTUUID=$partuuid" >> mountpoint/etc/default/grub.d/40-force-partuuid
364+ chroot mountpoint update-grub
365+ fi
366 fi
367
368 if [ "$ARCH" = "s390x" ]; then
369
370=== modified file 'live-build/ubuntu-cpc/hooks/033-disk-image-uefi.binary'
371--- live-build/ubuntu-cpc/hooks/033-disk-image-uefi.binary 2017-09-19 20:45:37 +0000
372+++ live-build/ubuntu-cpc/hooks/033-disk-image-uefi.binary 2017-10-03 22:07:43 +0000
373@@ -61,6 +61,14 @@
374 efi_boot_dir="/boot/efi/EFI/BOOT"
375 chroot mountpoint mkdir -p "${efi_boot_dir}"
376
377+ if [ "${SUBPROJECT:-}" = minimized ] && [ -n "$partuuid" ]; then
378+ # FIXME: code duplicated between 032-disk-image.binary
379+ # and 033-disk-image-uefi.binary. We want to fix this to not
380+ # have initramfs-tools installed at all on these images.
381+ echo "partuuid found for root device; omitting initrd"
382+ echo "GRUB_FORCE_PARTUUID=$partuuid" >> mountpoint/etc/default/grub.d/40-force-partuuid
383+ fi
384+
385 chroot mountpoint apt-get -y update
386
387 # The modules below only make sense on non-Secure Boot UEFI systems.
388@@ -132,6 +140,8 @@
389 create_partitions "${disk_image}"
390 mount_image "${disk_image}" 1
391
392+partuuid=$(blkid -s PARTUUID -o value "$rootfs_dev_mapper")
393+
394 # Copy the chroot in to the disk
395 make_ext4_partition "${rootfs_dev_mapper}"
396 mkdir mountpoint
397
398=== modified file 'live-build/ubuntu-cpc/hooks/999-cpc-fixes.chroot'
399--- live-build/ubuntu-cpc/hooks/999-cpc-fixes.chroot 2016-04-14 18:06:33 +0000
400+++ live-build/ubuntu-cpc/hooks/999-cpc-fixes.chroot 2017-10-03 22:07:43 +0000
401@@ -3,6 +3,8 @@
402 root_fs_label=cloudimg-rootfs
403 set -ex
404
405+. /root/config/chroot
406+
407 CLOUD_IMG_STR="# CLOUD_IMG: This file was created/modified by the Cloud Image build process"
408
409 LANG=C
410@@ -87,7 +89,9 @@
411 _xchroot "${rootd}" sh -c 'rm -f /etc/ssh/ssh_host_[rd]sa_key*'
412
413 ## --------------
414-_xchroot "${rootd}" locale-gen en_US.utf8
415+if [ "${SUBPROJECT:-}" != minimized ]; then
416+ _xchroot "${rootd}" locale-gen en_US.utf8
417+fi
418
419 ## --------------
420 # set cloud-init to be on

Subscribers

People subscribed via source and target branches