Merge lp:~jibel/livecd-rootfs/add_multi_layered_squashfses_support into lp:livecd-rootfs
- add_multi_layered_squashfses_support
- Merge into trunk
Status: | Merged |
---|---|
Merge reported by: | Steve Langasek |
Merged at revision: | not available |
Proposed branch: | lp:~jibel/livecd-rootfs/add_multi_layered_squashfses_support |
Merge into: | lp:livecd-rootfs |
Diff against target: |
1242 lines (+808/-255) 7 files modified
debian/tests/default-bootstraps (+1/-0) live-build/auto/build (+137/-185) live-build/auto/clean (+2/-0) live-build/auto/config (+92/-64) live-build/functions (+198/-6) live-build/lb_binary_layered (+132/-0) live-build/lb_chroot_layered (+246/-0) |
To merge this branch: | bzr merge lp:~jibel/livecd-rootfs/add_multi_layered_squashfses_support |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Steve Langasek | Needs Fixing | ||
Review via email: mp+358490@code.launchpad.net |
Commit message
Description of the change
Adds support for multi layer filesystem by generating one squashfs per layer and adding a new 'live-layered' image format.
squashfs are numbered so the order is preserved and mounted in order by casper.
Seeding of snap packages and seeds corresponding to the layers are not
available yet and will be proposed in the subsequent merge proposal.
Dimitri John Ledkov (xnox) wrote : | # |
Jean-Baptiste Lallement (jibel) wrote : | # |
Thanks for the review
On 14/11/2018 00:35, Dimitri John Ledkov wrote:
>
> In passes, how does one specify multiple branches of stacks? Or is only a linear stack allowed by this code?
This code only allows linear stacks to avoid not make current code more
complex than it already is and diverging too much from existing logic.
Our approach is to define the stacking defining the live image in PASSES
and put the extra logic like “branched mounts” in hooks.
For instance with langpacks which is the use case for Desktop image, we
also have multiple branches of stacks. It is difficult to represent the
structure in a generic way and it adds extra complexity to the
maintenance of those definitions.
Following your proposal to represent the layers structure as a list, it
would be something like:
PASSES=
desktop-
desktop-
We thus have multiple “base” here, “desktop-minimal” or
“desktop-
appropriate here.
In a tree, it’s not better:
- desktop-min
- desktop
- Lang-neg-de
- Lang-neg-fr
- Lang-neg-es
- …
- Live
- Lang-neg-min-de
- Lang-neg-min-fr
- Lang-neg-min-es
- …
Addition or removal of any default language would be then error-prone.
This is to compare with a hook, where we just loop over “desktop-min”
and creates langpacks negative stacks, and then looping over “desktop”
as well to achieve the same. Besides, shell seems inappropriate to
implement this type of logic.
Note that the current implementation is similar than existing
ubuntu-server:live logic (just a little bit more generic) and we made
sure we didn’t break your use case. Note that though, you will be able
to remove your first hook, creating the “live” stack using the generic
code right now. However, the maas-* stacks will still be in hooks.
>
> Cause the current subiquity images do not have `live` as the top of the stack.... They do this:
>
> +--> Base +-----> Live
> |
> +-----> Rack +---> Region
>
> Because I am expecting to have the ability to somehow specify what each pass depends on. But it looks like the base for a subsequent pass, is always the previous one?!
>
>
> It would be nice to extend PASS syntax to optionally accept an arbitrary `base`, e.g.
>
> PASSES="base rack region base:live" to encode the above graph, and such that `base:live` pass uses base as the lowerdir, instead of region (i.e. the previous pass result).
>
> Or something...
>
> not sure if : is acceptable pair delimiter here, or not.
>
> Also not sure if we want to always enforce specifying `base` such that we can construct multiple root nodes in one go. E.g. `base base:rack rack:region base:live` or `:base rack region base:live` for the above graph.
>
> Or like maybe always list all layers?! but that violates donot-repeat-
>
> ===
>
> When calling includes/hooks are they aware which pass they are for? what is the source dir for each pass, for e.g. bina...
Steve Langasek (vorlon) wrote : | # |
Thanks for working on this, it will be nice to have cleaner handling of the desktop-minimal stuff included here in livecd-rootfs.
I would like to see this converged with the ubuntu-server-live handling as part of landing of this branch (see also Dimitri's review comments). You've gone to some length to implement this in a way that's generalizable across projects, so we ought to make sure the implementation is actually reusable by the only other image that currently uses layered squashfs.
Jean-Baptiste Lallement (jibel) wrote : | # |
We intended to propose several MP for snap and “sub-layers” to reduce the complexity of the review, but we’ll finally merge them into this one so you’ll have a good understanding of the full implementation.
Supporting the server-live use case adds makes the implementation more complex due to its specific requirements (hooks and includes). But we agree that a more generalizable implementation is better, so let’s spend some time to ensure those 2 additional requirements are supported, and once foundation/server team want to switch to it, that they will not encounter any major limitations.
Jean-Baptiste Lallement (jibel) wrote : | # |
Following previous comments, this MP has been updated with these changes:
- Merged preseeding of snap packages and adds snap packages to the image manifest.
- Added lb_binary_layered to handle multi branches of squashfses with sublayers.
- Factorized several helpers called by lb_chroot_layered
- Removed obsolete chroot helpers from lb_chroot_layered and minor cleanup.
- Renamed subproject layered -> ubiquity-ng
- Use PASSES instead of IMAGEFORMAT to detect a multilayer project. Defining PASSES switches the image build into layered build.
- Adds includes by pass to customize chroot for specific passes.
- Moved back specific helpers and functions from functions to config.
- For Ubuntu Desktop:
These changes have been tested against ubuntu-server live which still uses its current implementation (with maas-region and maas-rack squashfses built in hooks).
All the requirements of ubuntu-server:live can be ported from the current hooks to the new implementation of the layered images.
To do so:
- The project have to define PASSES.
- Snaps and packages for sublayers added to separated seeds and referenced in auto/config.
- Layers must be customized with chroot hooks (eg to modify existing files) and chroot includes (eg to add new files) depending on PASS.
Ubuntu Desktop (standard disco) has been modified to use layered images as requested. As a consequence the following MPs must be reviewed together with this one and released before uploading livecd-rootfs:
- debian-cd: https:/
- ubuntu-cdimage: https:/
The subproject ubiquity-ng must be created for building the ubuntu-
This whole set of changes (livecd-rootfs, ubuntu-cdimage and debian-cd) have been tested with the following projects:
- Ubuntu Desktop layered (iso) (disco) -> test new set of layers
- Ubuntu Desktop unlayered (iso) (disco) -> test previous image format (one squashfs)
- Ubuntu Desktop ubiquity-ng (iso) -> test new set of layers + sublayers
- Ubuntu Server live (iso) (bionic and disco) -> test backward compatibility with current server image and hooks impacts.
- Lubuntu (rootfs only, no local archive with universe for building iso, similar build to ubuntu-
- Ubuntu Mate (rootfs only, no local archive with universe for building iso, similar build to ubuntu-
Adam Conrad (adconrad) wrote : | # |
I don't have time for a full review this morning, but unless we intend to keep these forked from the "real" ISOs for testing for a while, and then converge, I really don't like the SUBPROJECT use here. I'd expect the real 'ubuntu' project to be building these, not some ubuntu-
As noted, you already can decide if you're building this type of image based on PASSES being defined, so it seems a bit odd to then also key on a subproject name.
- 1758. By Jean-Baptiste Lallement
-
configure network manager _after_ installing network-manager
Jean-Baptiste Lallement (jibel) wrote : | # |
> I don't have time for a full review this morning, but unless we intend to keep
> these forked from the "real" ISOs for testing for a while, and then converge,
> I really don't like the SUBPROJECT use here. I'd expect the real 'ubuntu'
> project to be building these, not some ubuntu-
>
> As noted, you already can decide if you're building this type of image based
> on PASSES being defined, so it seems a bit odd to then also key on a
> subproject name.
We need a subproject because the real 'ubuntu' and the new installer work will diverge quickly. Note that Ubuntu Desktop uses the layer system on Disco with this merge proposal without defining a subproject.
Balint Reczey (rbalint) wrote : | # |
The target Bazaar branch is not active anymore.
Please resubmit the merge proposal against https:/
Steve Langasek (vorlon) wrote : | # |
This is done now in git.
Preview Diff
1 | === modified file 'debian/tests/default-bootstraps' |
2 | --- debian/tests/default-bootstraps 2018-05-09 02:12:15 +0000 |
3 | +++ debian/tests/default-bootstraps 2018-11-28 08:47:44 +0000 |
4 | @@ -23,6 +23,7 @@ |
5 | lubuntu:: |
6 | mythbuntu:: |
7 | ubuntu:: |
8 | + ubuntu:ubiquity-ng: |
9 | ubuntu-base:: |
10 | ubuntu-budgie:: |
11 | ubuntu-budgie-desktop:: |
12 | |
13 | === modified file 'live-build/auto/build' |
14 | --- live-build/auto/build 2018-11-26 12:03:24 +0000 |
15 | +++ live-build/auto/build 2018-11-28 08:47:44 +0000 |
16 | @@ -252,107 +252,57 @@ |
17 | dpkg-divert --quiet --remove --rename /usr/sbin/update-initramfs |
18 | EOF |
19 | |
20 | - lb chroot "$@" |
21 | - |
22 | - if [ "${SUBPROJECT:-}" = minimized ]; then |
23 | - # force removal of initramfs-tools, which we assert is not |
24 | - # required for any minimized images but is still pulled in by |
25 | - # default |
26 | - # also remove landscape-common, which is heavyweight and |
27 | - # in the server seed only to provide /etc/motd content which |
28 | - # would only be seen by humans |
29 | - Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
30 | - apt-get -y purge initramfs-tools busybox-initramfs \ |
31 | - busybox-static landscape-common" |
32 | - # and if initramfs-tools was configured before our kernel, |
33 | - # /etc/kernel/postinst.d/initramfs-tools will have created |
34 | - # an initramfs despite the generic dpkg-divert; so remove it |
35 | - # here. |
36 | - rm -f chroot/boot/initrd.img-* |
37 | - |
38 | - # temporary workaround: don't remove linux-base which |
39 | - # may have no other reverse-depends currently |
40 | - Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
41 | - apt-mark manual linux-base" |
42 | - Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
43 | - apt-get -y --purge autoremove" |
44 | - fi |
45 | - |
46 | - # remove crufty files that shouldn't be left in an image |
47 | - rm -f chroot/var/cache/debconf/*-old chroot/var/lib/dpkg/*-old |
48 | - Chroot chroot apt clean |
49 | - if [ "${PROJECT}:${SUBPROJECT:-}" = "ubuntu-base:minimized" ]; then |
50 | - # Save even more size by removing apt lists (that are currently removed |
51 | - # downstream anyway) |
52 | - rm -rf chroot/var/lib/apt/lists/* |
53 | - # Having device notes in the docker image can cause problems |
54 | - # (https://github.com/tianon/docker-brew-ubuntu-core/issues/62) |
55 | - # so remove them. We only do this for docker out of an |
56 | - # abundance of caution. |
57 | - rm -rf chroot/dev/* |
58 | - fi |
59 | - |
60 | - if [ -f config/universe-enabled ]; then |
61 | - |
62 | -# This is cargo-culted almost verbatim (with some syntax changes for |
63 | -# preinstalled being slightly different in what it doesn't ask) from |
64 | -# debian-installer's apt-setup: |
65 | - |
66 | -cat > chroot/etc/apt/sources.list << EOF |
67 | -# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to |
68 | -# newer versions of the distribution. |
69 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted |
70 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted |
71 | - |
72 | -## Major bug fix updates produced after the final release of the |
73 | -## distribution. |
74 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted |
75 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted |
76 | - |
77 | -## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
78 | -## team. Also, please note that software in universe WILL NOT receive any |
79 | -## review or updates from the Ubuntu security team. |
80 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe |
81 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe |
82 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe |
83 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe |
84 | - |
85 | -## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
86 | -## team, and may not be under a free licence. Please satisfy yourself as to |
87 | -## your rights to use the software. Also, please note that software in |
88 | -## multiverse WILL NOT receive any review or updates from the Ubuntu |
89 | -## security team. |
90 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse |
91 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse |
92 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse |
93 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse |
94 | - |
95 | -## N.B. software from this repository may not have been tested as |
96 | -## extensively as that contained in the main release, although it includes |
97 | -## newer versions of some applications which may provide useful features. |
98 | -## Also, please note that software in backports WILL NOT receive any review |
99 | -## or updates from the Ubuntu security team. |
100 | -deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse |
101 | -# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse |
102 | - |
103 | -## Uncomment the following two lines to add software from Canonical's |
104 | -## 'partner' repository. |
105 | -## This software is not part of Ubuntu, but is offered by Canonical and the |
106 | -## respective vendors as a service to Ubuntu users. |
107 | -# deb http://archive.canonical.com/ubuntu $LB_DISTRIBUTION partner |
108 | -# deb-src http://archive.canonical.com/ubuntu $LB_DISTRIBUTION partner |
109 | - |
110 | -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted |
111 | -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted |
112 | -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe |
113 | -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe |
114 | -deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse |
115 | -# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse |
116 | -EOF |
117 | - |
118 | - fi |
119 | - if [ -d chroot/var/lib/preinstalled-pool ]; then |
120 | - cat > config/indices/apt.conf <<-EOF |
121 | + if [ -n "${PASSES}" ]; then |
122 | + PATH="config/:$PATH" lb chroot_layered "$@" |
123 | + else |
124 | + lb chroot "$@" |
125 | + fi |
126 | + |
127 | + # Let all configuration non multi-layered project here. |
128 | + # If those are moving to a multi-layer layout, this needs to be |
129 | + # done in chroot hooks. |
130 | + if [ -z "$PASSES" ]; then |
131 | + if [ "${SUBPROJECT:-}" = minimized ]; then |
132 | + # force removal of initramfs-tools, which we assert is not |
133 | + # required for any minimized images but is still pulled in by |
134 | + # default |
135 | + # also remove landscape-common, which is heavyweight and |
136 | + # in the server seed only to provide /etc/motd content which |
137 | + # would only be seen by humans |
138 | + Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
139 | + apt-get -y purge initramfs-tools busybox-initramfs \ |
140 | + busybox-static landscape-common" |
141 | + # and if initramfs-tools was configured before our kernel, |
142 | + # /etc/kernel/postinst.d/initramfs-tools will have created |
143 | + # an initramfs despite the generic dpkg-divert; so remove it |
144 | + # here. |
145 | + rm -f chroot/boot/initrd.img-* |
146 | + |
147 | + # temporary workaround: don't remove linux-base which |
148 | + # may have no other reverse-depends currently |
149 | + Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
150 | + apt-mark manual linux-base" |
151 | + Chroot chroot "env DEBIAN_FRONTEND=noninteractive \ |
152 | + apt-get -y --purge autoremove" |
153 | + fi |
154 | + |
155 | + clean_debian_chroot |
156 | + |
157 | + if [ "${PROJECT}:${SUBPROJECT:-}" = "ubuntu-base:minimized" ]; then |
158 | + # Save even more size by removing apt lists (that are currently removed |
159 | + # downstream anyway) |
160 | + rm -rf chroot/var/lib/apt/lists/* |
161 | + # Having device notes in the docker image can cause problems |
162 | + # (https://github.com/tianon/docker-brew-ubuntu-core/issues/62) |
163 | + # so remove them. We only do this for docker out of an |
164 | + # abundance of caution. |
165 | + rm -rf chroot/dev/* |
166 | + fi |
167 | + |
168 | + configure_universe |
169 | + |
170 | + if [ -d chroot/var/lib/preinstalled-pool ]; then |
171 | + cat > config/indices/apt.conf <<-EOF |
172 | Dir { |
173 | ArchiveDir "chroot/var/lib/preinstalled-pool"; |
174 | OverrideDir "config/indices"; |
175 | @@ -369,11 +319,11 @@ |
176 | Contents " "; |
177 | } |
178 | EOF |
179 | - for component in $LB_PARENT_ARCHIVE_AREAS; do |
180 | - mkdir -p chroot/var/lib/preinstalled-pool/dists/$LB_DISTRIBUTION/$component/binary-$LB_ARCHITECTURES |
181 | - done |
182 | - apt-ftparchive generate config/indices/apt.conf |
183 | - cat << @@EOF > chroot/etc/apt/sources.list.preinstall |
184 | + for component in $LB_PARENT_ARCHIVE_AREAS; do |
185 | + mkdir -p chroot/var/lib/preinstalled-pool/dists/$LB_DISTRIBUTION/$component/binary-$LB_ARCHITECTURES |
186 | + done |
187 | + apt-ftparchive generate config/indices/apt.conf |
188 | + cat << @@EOF > chroot/etc/apt/sources.list.preinstall |
189 | # This is a sources.list entry for a small pool of packages |
190 | # provided on your preinstalled filesystem for your convenience. |
191 | # |
192 | @@ -385,93 +335,89 @@ |
193 | # |
194 | @@EOF |
195 | |
196 | - cp chroot/etc/apt/sources.list chroot/etc/apt/sources.list.orig |
197 | - cp chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list |
198 | - |
199 | - echo "Waiting on gnupg ("$GPG_PROCESS") to finish generating a key." |
200 | - wait $GPG_PROCESS |
201 | - |
202 | - R_ORIGIN=$(lsb_release -i -s) |
203 | - R_CODENAME=$(lsb_release -c -s) |
204 | - R_VERSION=$(lsb_release -r -s) |
205 | - R_PRETTYNAME=$(echo $R_CODENAME | sed -e 's/^\(.\)/\U\1/') |
206 | - |
207 | - apt-ftparchive -o APT::FTPArchive::Release::Origin=$R_ORIGIN \ |
208 | - -o APT::FTPArchive::Release::Label=$R_ORIGIN \ |
209 | - -o APT::FTPArchive::Release::Suite=$R_CODENAME-local \ |
210 | - -o APT::FTPArchive::Release::Version=$R_VERSION \ |
211 | - -o APT::FTPArchive::Release::Codename=$R_CODENAME \ |
212 | - -o APT::FTPArchive::Release::Description="$R_ORIGIN $R_PRETTYNAME Local" \ |
213 | - release chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/ \ |
214 | - > config/gnupg/Release |
215 | - |
216 | - gpg --home config/gnupg --detach-sign --armor config/gnupg/Release |
217 | - mv config/gnupg/Release \ |
218 | - chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release |
219 | - mv config/gnupg/Release.asc \ |
220 | - chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release.gpg |
221 | - apt-key --keyring chroot/etc/apt/trusted.gpg add config/gnupg/pubring.gpg |
222 | - find chroot/var/lib/preinstalled-pool/ -name Packages | xargs rm |
223 | - |
224 | - Chroot chroot "apt-get update" |
225 | - cat chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig \ |
226 | - > chroot/etc/apt/sources.list |
227 | - rm chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig |
228 | - fi |
229 | - case $PROJECT:$SUBPROJECT in |
230 | - *) |
231 | - if [ -e "config/seeded-snaps" ]; then |
232 | - snap_list=$(cat config/seeded-snaps) |
233 | - preinstall_snaps $snap_list |
234 | - fi |
235 | - ;; |
236 | - esac |
237 | - |
238 | - if [ "$PROJECT" = "ubuntu-touch" ] || [ "$PROJECT" = "ubuntu-touch-custom" ]; then |
239 | - if [ "$ARCH" = "armhf" ]; then |
240 | - INFO_DESC="$(lsb_release -d -s)" |
241 | - echo "$INFO_DESC - $ARCH ($BUILDSTAMP)" >chroot/etc/media-info |
242 | - mkdir -p chroot/var/log/installer |
243 | - Chroot chroot "ln -s /etc/media-info /var/log/installer/media-info" |
244 | - fi |
245 | - fi |
246 | - if [ "$PROJECT" = "ubuntu-cpc" ]; then |
247 | - if [ "${SUBPROJECT:-}" = minimized ]; then |
248 | - BUILD_NAME=minimal |
249 | - else |
250 | - BUILD_NAME=server |
251 | - fi |
252 | - cat > chroot/etc/cloud/build.info << EOF |
253 | + cp chroot/etc/apt/sources.list chroot/etc/apt/sources.list.orig |
254 | + cp chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list |
255 | + |
256 | + echo "Waiting on gnupg ("$GPG_PROCESS") to finish generating a key." |
257 | + wait $GPG_PROCESS |
258 | + |
259 | + R_ORIGIN=$(lsb_release -i -s) |
260 | + R_CODENAME=$(lsb_release -c -s) |
261 | + R_VERSION=$(lsb_release -r -s) |
262 | + R_PRETTYNAME=$(echo $R_CODENAME | sed -e 's/^\(.\)/\U\1/') |
263 | + |
264 | + apt-ftparchive -o APT::FTPArchive::Release::Origin=$R_ORIGIN \ |
265 | + -o APT::FTPArchive::Release::Label=$R_ORIGIN \ |
266 | + -o APT::FTPArchive::Release::Suite=$R_CODENAME-local \ |
267 | + -o APT::FTPArchive::Release::Version=$R_VERSION \ |
268 | + -o APT::FTPArchive::Release::Codename=$R_CODENAME \ |
269 | + -o APT::FTPArchive::Release::Description="$R_ORIGIN $R_PRETTYNAME Local" \ |
270 | + release chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/ \ |
271 | + > config/gnupg/Release |
272 | + |
273 | + gpg --home config/gnupg --detach-sign --armor config/gnupg/Release |
274 | + mv config/gnupg/Release \ |
275 | + chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release |
276 | + mv config/gnupg/Release.asc \ |
277 | + chroot/var/lib/preinstalled-pool/dists/$R_CODENAME/Release.gpg |
278 | + apt-key --keyring chroot/etc/apt/trusted.gpg add config/gnupg/pubring.gpg |
279 | + find chroot/var/lib/preinstalled-pool/ -name Packages | xargs rm |
280 | + |
281 | + Chroot chroot "apt-get update" |
282 | + cat chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig \ |
283 | + > chroot/etc/apt/sources.list |
284 | + rm chroot/etc/apt/sources.list.preinstall chroot/etc/apt/sources.list.orig |
285 | + fi |
286 | + case $PROJECT:$SUBPROJECT in |
287 | + ubuntu-server:live) |
288 | + lb chroot_resolv install |
289 | + snap_prepare chroot |
290 | + lb chroot_resolv remove |
291 | + ;; |
292 | + *) |
293 | + if [ -e "config/seeded-snaps" ]; then |
294 | + snap_list=$(cat config/seeded-snaps) |
295 | + preinstall_snaps $snap_list |
296 | + fi |
297 | + ;; |
298 | + esac |
299 | + |
300 | + if [ "$PROJECT" = "ubuntu-touch" ] || [ "$PROJECT" = "ubuntu-touch-custom" ]; then |
301 | + if [ "$ARCH" = "armhf" ]; then |
302 | + INFO_DESC="$(lsb_release -d -s)" |
303 | + echo "$INFO_DESC - $ARCH ($BUILDSTAMP)" >chroot/etc/media-info |
304 | + mkdir -p chroot/var/log/installer |
305 | + Chroot chroot "ln -s /etc/media-info /var/log/installer/media-info" |
306 | + fi |
307 | + fi |
308 | + if [ "$PROJECT" = "ubuntu-cpc" ]; then |
309 | + if [ "${SUBPROJECT:-}" = minimized ]; then |
310 | + BUILD_NAME=minimal |
311 | + else |
312 | + BUILD_NAME=server |
313 | + fi |
314 | + cat > chroot/etc/cloud/build.info << EOF |
315 | build_name: $BUILD_NAME |
316 | serial: $BUILDSTAMP |
317 | EOF |
318 | + fi |
319 | + |
320 | + configure_network_manager |
321 | + |
322 | + echo "===== Checking size of /usr/share/doc =====" |
323 | + echo BEGIN docdirs |
324 | + (cd chroot && find usr/share/doc -maxdepth 1 -type d | xargs du -s | sort -nr) |
325 | + echo END docdirs |
326 | + |
327 | + /usr/share/livecd-rootfs/minimize-manual chroot |
328 | fi |
329 | |
330 | - # If the image pre-installs network-manager, let it manage all devices by |
331 | - # default. Installing NM on an existing system only manages wifi and wwan via |
332 | - # /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf. When setting |
333 | - # the global backend to NM, netplan overrides that file. |
334 | - if [ -d chroot/usr/lib/NetworkManager ]; then |
335 | - echo "===== Enabling all devices in NetworkManager ====" |
336 | - mkdir -p chroot/etc/netplan |
337 | - cat <<EOF > chroot/etc/netplan/01-network-manager-all.yaml |
338 | -# Let NetworkManager manage all devices on this system |
339 | -network: |
340 | - version: 2 |
341 | - renderer: NetworkManager |
342 | -EOF |
343 | + if [ -n "${PASSES}" ]; then |
344 | + PATH="config/:$PATH" lb binary_layered "$@" |
345 | else |
346 | - echo "==== NetworkManager not installed ====" |
347 | + lb binary "$@" |
348 | fi |
349 | |
350 | - echo "===== Checking size of /usr/share/doc =====" |
351 | - echo BEGIN docdirs |
352 | - (cd chroot && find usr/share/doc -maxdepth 1 -type d | xargs du -s | sort -nr) |
353 | - echo END docdirs |
354 | - |
355 | - /usr/share/livecd-rootfs/minimize-manual chroot |
356 | - |
357 | - lb binary "$@" |
358 | touch binary.success |
359 | ) 2>&1 | tee binary.log |
360 | |
361 | @@ -504,6 +450,12 @@ |
362 | chmod 644 "$PREFIX.$OUTPUT" |
363 | done |
364 | |
365 | +# we don't need a manifest-remove for a layered-aware installer |
366 | +if [ "$SUBPROJECT" = "ubiquity-ng" ]; then |
367 | + rm -f livecd.${PROJECT}-manifest-remove |
368 | + rm -f config/manifest-minimal-remove |
369 | +fi |
370 | + |
371 | if [ -e config/manifest-minimal-remove ]; then |
372 | cp config/manifest-minimal-remove "$PREFIX.manifest-minimal-remove" |
373 | fi |
374 | |
375 | === modified file 'live-build/auto/clean' |
376 | --- live-build/auto/clean 2012-11-19 18:49:31 +0000 |
377 | +++ live-build/auto/clean 2018-11-28 08:47:44 +0000 |
378 | @@ -8,3 +8,5 @@ |
379 | rm -f binary.manifest binary.manifest-desktop binary.log |
380 | rm -f livecd.* |
381 | rm -rf userdata |
382 | +rm -rf chroot.* |
383 | +rm -rf *.manifest.full |
384 | |
385 | === modified file 'live-build/auto/config' |
386 | --- live-build/auto/config 2018-11-23 16:39:40 +0000 |
387 | +++ live-build/auto/config 2018-11-28 08:47:44 +0000 |
388 | @@ -33,15 +33,40 @@ |
389 | |
390 | mkdir -p config |
391 | cp -af /usr/share/livecd-rootfs/live-build/functions config/functions |
392 | +cp -af /usr/share/livecd-rootfs/live-build/lb_*_layered config/ |
393 | cp -af /usr/share/livecd-rootfs/live-build/snap-seed-parse.py config/snap-seed-parse |
394 | |
395 | mkdir -p config/package-lists |
396 | |
397 | +. config/functions |
398 | + |
399 | +OPTS= |
400 | +COMPONENTS= |
401 | +BINARY_REMOVE_LINUX=: |
402 | +BINARY_IMAGES=none |
403 | +MEMTEST=none |
404 | +SOURCE='--source false' |
405 | +BOOTLOADER=none |
406 | +BOOTAPPEND_LIVE= |
407 | +LIVE_TASK= |
408 | +PREINSTALLED=false |
409 | +PREINSTALL_POOL= |
410 | +PREINSTALL_POOL_SEEDS= |
411 | +PREFIX="livecd.$PROJECT${SUBARCH:+-$SUBARCH}" |
412 | + |
413 | +CHROOT_HOOKS= |
414 | +BINARY_HOOKS= |
415 | + |
416 | +APT_OPTIONS=" --yes -oDebug::pkgDepCache::AutoInstall=yes " |
417 | + |
418 | add_task () |
419 | { |
420 | local pass="$1" |
421 | shift |
422 | local task |
423 | + local snap_list_file |
424 | + local snap_list_files |
425 | + local curseed |
426 | |
427 | # The removal of direct task installation support from live-build |
428 | # poses some problems. If the chroot has multiarch configured - for |
429 | @@ -58,12 +83,32 @@ |
430 | # probably a lurking timebomb that we need to fix. In the meantime, |
431 | # the Architecture restriction at least saves us from abject |
432 | # failure. |
433 | + # |
434 | + # We want as well to grab the snap list for each PASS. Resolve for all |
435 | + # given task, and deduplicate them to generate snaps for the PASS. |
436 | |
437 | for task; do |
438 | # We need a ridiculous number of backslashes to protect |
439 | # parentheses from eval. |
440 | echo "!chroot chroot apt-cache dumpavail | grep-dctrl -nsPackage \\\\\\( -XFArchitecture $ARCH -o -XFArchitecture all \\\\\\) -a -wFTask $task" >> "config/package-lists/livecd-rootfs.list.chroot_$pass" |
441 | + |
442 | + curseed=$(seed_from_task ${task}) |
443 | + if [ -z "${curseed}" ]; then |
444 | + echo "W: No seed matching task ${task}" |
445 | + continue |
446 | + fi |
447 | + snap_list_file="config/package-lists/seed.${curseed}.snaplist.full" |
448 | + snap_from_seed "${curseed}" $snap_list_file |
449 | + if [ -e "$snap_list_file" ]; then |
450 | + snap_list_files="${snap_list_files} $snap_list_file" |
451 | + fi |
452 | done |
453 | + # The snap list is one line, and could be duplicated between seeds via inheritance. |
454 | + # Uniquely sort them and store them back in one line. |
455 | + if [ -n "${snap_list_files}" ]; then |
456 | + cat ${snap_list_files}|xargs -n1|sort -u > "config/package-lists/livecd-rootfs.snaplist.chroot_${pass}.full" |
457 | + rm ${snap_list_files} |
458 | + fi |
459 | } |
460 | |
461 | add_package () |
462 | @@ -77,24 +122,34 @@ |
463 | done |
464 | } |
465 | |
466 | -OPTS= |
467 | -COMPONENTS= |
468 | -BINARY_REMOVE_LINUX=: |
469 | -BINARY_IMAGES=none |
470 | -MEMTEST=none |
471 | -SOURCE='--source false' |
472 | -BOOTLOADER=none |
473 | -BOOTAPPEND_LIVE= |
474 | -LIVE_TASK= |
475 | -PREINSTALLED=false |
476 | -PREINSTALL_POOL= |
477 | -PREINSTALL_POOL_SEEDS= |
478 | -PREFIX="livecd.$PROJECT${SUBARCH:+-$SUBARCH}" |
479 | - |
480 | -CHROOT_HOOKS= |
481 | -BINARY_HOOKS= |
482 | - |
483 | -APT_OPTIONS=" --yes -oDebug::pkgDepCache::AutoInstall=yes " |
484 | +add_layered_pass() { |
485 | + # Add a layer to an existing pass based on seeds matching a regexp |
486 | + # $1 base pass |
487 | + # $2 seeds (regexp) |
488 | + |
489 | + for seed in $(ls config/germinate-output/|grep -P "$2"); do |
490 | + pass=${1}_${seed} |
491 | + list_packages_from_seed ${seed} >> config/package-lists/livecd-rootfs.list.chroot_$pass |
492 | + done |
493 | +} |
494 | + |
495 | +add_layered_pass_delta() { |
496 | + # Add a layer to an existing pass based on delta between seeds matching a regexp and a base seed |
497 | + # $1 base pass |
498 | + # $2 base seed |
499 | + # $3 seeds to remove from base seed (regexp). If empty, a no-<base-seed> sublayer is generated. |
500 | + |
501 | + local seed_regexp="$3" |
502 | + if [ -z "${seed_regexp}" ]; then |
503 | + substract_package_lists ${2} "" >> config/package-lists/livecd-rootfs.removal-list.chroot_${1}_no-${2} |
504 | + return |
505 | + fi |
506 | + |
507 | + for seed in $(ls config/germinate-output/|grep -P "$seed_regexp"); do |
508 | + pass=${1}_${seed} |
509 | + substract_package_lists ${2} ${seed} >> config/package-lists/livecd-rootfs.removal-list.chroot_$pass |
510 | + done |
511 | +} |
512 | |
513 | add_chroot_hook () |
514 | { |
515 | @@ -288,30 +343,6 @@ |
516 | OPTS="${OPTS:+$OPTS }--bootstrap-flavour=minimal --linux-packages=linux-image" |
517 | fi |
518 | |
519 | -# cribbed from cdimage, perhaps this should be a small helper script in germinate? |
520 | -add_inheritance () { |
521 | - case " $inherit " in |
522 | - *" $1 "*) |
523 | - ;; |
524 | - *) |
525 | - inherit="${inherit:+$inherit }$1" |
526 | - ;; |
527 | - esac |
528 | -} |
529 | - |
530 | -expand_inheritance () { |
531 | - for seed in $(grep "^$1:" config/germinate-output/structure | cut -d: -f2); do |
532 | - expand_inheritance "$seed" |
533 | - done |
534 | - add_inheritance "$1" |
535 | -} |
536 | - |
537 | -inheritance () { |
538 | - inherit= |
539 | - expand_inheritance "$1" |
540 | - echo "$inherit" |
541 | -} |
542 | - |
543 | mkdir -p config/germinate-output |
544 | case $PROJECT in |
545 | kubuntu-active*) |
546 | @@ -358,8 +389,21 @@ |
547 | |
548 | case $PROJECT in |
549 | ubuntu|ubuntu-dvd) |
550 | - add_task install minimal standard ubuntu-desktop |
551 | + PASSES="install-minimal install live" |
552 | + add_task install-minimal minimal standard ubuntu-desktop-minimal ubuntu-desktop-minimal-default-languages |
553 | + add_task install ubuntu-desktop ubuntu-desktop-default-languages |
554 | LIVE_TASK='ubuntu-live' |
555 | + |
556 | + case ${SUBPROJECT:-} in |
557 | + ubiquity-ng) |
558 | + # LANG PASS for minimal and install |
559 | + add_layered_pass_delta install-minimal desktop-minimal-default-languages '^desktop-minimal-(?!default-languages)[^.]+$' |
560 | + add_layered_pass_delta install-minimal desktop-minimal-default-languages '' # none (if no default langpack is selected) |
561 | + add_layered_pass_delta install desktop-default-languages '^desktop-(?!default-languages|minimal|common)[^.]+$' |
562 | + add_layered_pass_delta install desktop-default-languages '' # none (if no default langpack is selected) |
563 | + ;; |
564 | + esac |
565 | + |
566 | case $ARCH in |
567 | amd64) add_package live $SIGNED_KERNEL_PACKAGE ;; |
568 | esac |
569 | @@ -728,30 +772,11 @@ |
570 | ;; |
571 | ubuntu-server:live) |
572 | BASE_SEED='server' |
573 | - # subiquity is seeded but in a separate squashfs via hooks; set HOOK_SNAPS and ALL_SNAPS. |
574 | - HOOK_SNAPS='subiquity' |
575 | - ALL_SNAPS='' |
576 | ;; |
577 | esac |
578 | |
579 | -if [ -n "${BASE_SEED}" ]; then |
580 | - SEEDS_EXPANDED=$(inheritance ${BASE_SEED}) |
581 | - for seed in ${SEEDS_EXPANDED}; do |
582 | - echo "snap: considering ${seed}" |
583 | - file=config/germinate-output/${seed}.snaps |
584 | - [ -e "${file}" ] || continue |
585 | - # extract the first column (snap package name) from germinate's output |
586 | - # translate the human-readable "foo (classic)" into a |
587 | - # more machine readable "foo/classic" |
588 | - seed_snaps=$(sed -rn '1,/-----/d;/-----/,$d; s/(.*) \|.*/\1/; s, \(classic\),/classic,; p' "${file}") |
589 | - for snap in ${seed_snaps}; do |
590 | - echo "snap: found ${snap}" |
591 | - ALL_SNAPS="${ALL_SNAPS:+${ALL_SNAPS} }${snap}" |
592 | - done |
593 | - done |
594 | - if [ -n "${ALL_SNAPS}" ] || [ -n "${HOOK_SNAPS}" ]; then |
595 | - echo "${ALL_SNAPS}" > config/seeded-snaps |
596 | - fi |
597 | +if [ -z "$PASSES" ] && [ -n "${BASE_SEED}" ]; then |
598 | + snap_from_seed "${BASE_SEED}" config/seeded-snaps |
599 | fi |
600 | |
601 | # grab a list of packags to remove for a "minimal" installation from the seed |
602 | @@ -890,6 +915,9 @@ |
603 | echo "LB_CHROOT_HOOKS=\"$CHROOT_HOOKS\"" >> config/chroot |
604 | echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/chroot |
605 | echo "LB_DISTRIBUTION=\"$SUITE\"" >> config/chroot |
606 | +if [ -n "$PASSES" ]; then |
607 | + echo "PASSES=\"$PASSES\"" >> config/common |
608 | +fi |
609 | echo "LB_BINARY_HOOKS=\"$BINARY_HOOKS\"" >> config/binary |
610 | echo "BUILDSTAMP=\"$NOW\"" >> config/binary |
611 | echo "SUBPROJECT=\"${SUBPROJECT:-}\"" >> config/binary |
612 | |
613 | === modified file 'live-build/functions' |
614 | --- live-build/functions 2018-11-13 19:21:19 +0000 |
615 | +++ live-build/functions 2018-11-28 08:47:44 +0000 |
616 | @@ -373,6 +373,30 @@ |
617 | distro-info --series="$LB_DISTRIBUTION" -r | awk '{ print $1 }' |
618 | } |
619 | |
620 | +# cribbed from cdimage, perhaps this should be a small helper script in germinate? |
621 | +add_inheritance () { |
622 | + case " $inherit " in |
623 | + *" $1 "*) |
624 | + ;; |
625 | + *) |
626 | + inherit="${inherit:+$inherit }$1" |
627 | + ;; |
628 | + esac |
629 | +} |
630 | + |
631 | +expand_inheritance () { |
632 | + for seed in $(grep "^$1:" config/germinate-output/structure | cut -d: -f2); do |
633 | + expand_inheritance "$seed" |
634 | + done |
635 | + add_inheritance "$1" |
636 | +} |
637 | + |
638 | +inheritance () { |
639 | + inherit= |
640 | + expand_inheritance "$1" |
641 | + echo "$inherit" |
642 | +} |
643 | + |
644 | _snap_preseed() { |
645 | # Download the snap/assertion and add to the preseed |
646 | local CHROOT_ROOT=$1 |
647 | @@ -387,6 +411,12 @@ |
648 | |
649 | # Download the snap & assertion |
650 | local snap_download_failed=0 |
651 | + |
652 | + # Preseed a snap only once |
653 | + if [ -f ${snaps_dir}/${SNAP_NAME}_[0-9]*.snap ]; then |
654 | + return |
655 | + fi |
656 | + |
657 | chroot $CHROOT_ROOT sh -c " |
658 | set -x; |
659 | cd /var/lib/snapd/seed; |
660 | @@ -432,6 +462,10 @@ |
661 | local account_key_assertion="$assertions_dir/account-key" |
662 | local account_assertion="$assertions_dir/account" |
663 | |
664 | + if [ -d "$assertions_dir" ]; then |
665 | + return |
666 | + fi |
667 | + |
668 | mkdir -p "$assertions_dir" |
669 | mkdir -p "$snaps_dir" |
670 | |
671 | @@ -476,15 +510,10 @@ |
672 | # used for the image's model assertion |
673 | local CUSTOM_BRAND_MODEL=${2:-generic:generic-classic} |
674 | |
675 | - local seed_dir="$CHROOT_ROOT/var/lib/snapd/seed" |
676 | - local snaps_dir="$seed_dir/snaps" |
677 | - |
678 | snap_prepare_assertions "$CHROOT_ROOT" "$CUSTOM_BRAND_MODEL" |
679 | |
680 | # Download the core snap |
681 | - if ! [ -f $snaps_dir/core_[0-9]*.snap ] ; then |
682 | - _snap_preseed $CHROOT_ROOT core stable |
683 | - fi |
684 | + _snap_preseed $CHROOT_ROOT core stable |
685 | } |
686 | |
687 | snap_preseed() { |
688 | @@ -501,3 +530,166 @@ |
689 | fi |
690 | _snap_preseed $CHROOT_ROOT $SNAP $CHANNEL |
691 | } |
692 | + |
693 | +snap_from_seed() { |
694 | + local base_seed=$1 |
695 | + local out=$2 |
696 | + local all_snaps |
697 | + local seeds_expanded |
698 | + |
699 | + seeds_expanded=$(inheritance ${base_seed}) |
700 | + for seed in ${seeds_expanded}; do |
701 | + echo "snap: considering ${seed}" |
702 | + file=config/germinate-output/${seed}.snaps |
703 | + [ -e "${file}" ] || continue |
704 | + # extract the first column (snap package name) from germinate's output |
705 | + # translate the human-readable "foo (classic)" into a |
706 | + # more machine readable "foo/classic" |
707 | + seed_snaps=$(sed -rn '1,/-----/d;/-----/,$d; s/(.*) \|.*/\1/; s, \(classic\),/classic,; p' "${file}") |
708 | + for snap in ${seed_snaps}; do |
709 | + echo "snap: found ${snap}" |
710 | + all_snaps="${all_snaps:+${all_snaps} }${snap}" |
711 | + done |
712 | + done |
713 | + if [ -n "${all_snaps}" ]; then |
714 | + echo "${all_snaps}" > $out |
715 | + fi |
716 | +} |
717 | + |
718 | +seed_from_task () |
719 | +{ |
720 | + # Retrieve the name of the seed from a task name |
721 | + local task=$1 |
722 | + local seed |
723 | + local seedfile |
724 | + local seedfiles |
725 | + |
726 | + seedfile="$(grep -lE "^Task-Key: +${task}\$" config/germinate-output/*seedtext|head -1)" |
727 | + if [ -n "$seedfile" ]; then |
728 | + basename $seedfile .seedtext |
729 | + return |
730 | + fi |
731 | + |
732 | + seedfiles="$(grep -lE "^Task-Per-Derivative: *1\$" config/germinate-output/*seedtext)" |
733 | + if [ -n "$seedfiles" ]; then |
734 | + for seed in $(echo $seedfiles | xargs basename -s .seedtext); do |
735 | + if [ ${PROJECT}-${seed} = $task ]; then |
736 | + echo ${seed} |
737 | + return |
738 | + fi |
739 | + done |
740 | + fi |
741 | +} |
742 | + |
743 | +list_packages_from_seed () { |
744 | + # Store all packages for a given seed, including its seed dependency |
745 | + # $1: Name of the seed to expand to a package list |
746 | + |
747 | + local all_seeds="$(inheritance $1)" |
748 | + |
749 | + for seed in $all_seeds; do |
750 | + head -n-2 config/germinate-output/${seed}.seed|tail -n+3|awk '{print $1}' |
751 | + done|sort -u |
752 | +} |
753 | + |
754 | +substract_package_lists() { |
755 | + # Substract a package list from another |
756 | + # |
757 | + # $1 source package list |
758 | + # $2 Package list to substract from source package list |
759 | + local list1=$(mktemp) |
760 | + local list2=$(mktemp) |
761 | + |
762 | + list_packages_from_seed $1 > list1 |
763 | + list_packages_from_seed $2 > list2 |
764 | + comm -23 list1 list2 |
765 | + |
766 | + rm list1 |
767 | + rm list2 |
768 | +} |
769 | + |
770 | +clean_debian_chroot() { |
771 | + # remove crufty files that shouldn't be left in an image |
772 | + rm -f chroot/var/cache/debconf/*-old chroot/var/lib/dpkg/*-old |
773 | + Chroot chroot apt clean |
774 | +} |
775 | + |
776 | +configure_universe() { |
777 | + if [ -f config/universe-enabled ]; then |
778 | + # This is cargo-culted almost verbatim (with some syntax changes for |
779 | + # preinstalled being slightly different in what it doesn't ask) from |
780 | + # debian-installer's apt-setup: |
781 | + |
782 | + cat > chroot/etc/apt/sources.list << EOF |
783 | +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to |
784 | +# newer versions of the distribution. |
785 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted |
786 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION main restricted |
787 | + |
788 | +## Major bug fix updates produced after the final release of the |
789 | +## distribution. |
790 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted |
791 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates main restricted |
792 | + |
793 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
794 | +## team. Also, please note that software in universe WILL NOT receive any |
795 | +## review or updates from the Ubuntu security team. |
796 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe |
797 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION universe |
798 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe |
799 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates universe |
800 | + |
801 | +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu |
802 | +## team, and may not be under a free licence. Please satisfy yourself as to |
803 | +## your rights to use the software. Also, please note that software in |
804 | +## multiverse WILL NOT receive any review or updates from the Ubuntu |
805 | +## security team. |
806 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse |
807 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION multiverse |
808 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse |
809 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-updates multiverse |
810 | + |
811 | +## N.B. software from this repository may not have been tested as |
812 | +## extensively as that contained in the main release, although it includes |
813 | +## newer versions of some applications which may provide useful features. |
814 | +## Also, please note that software in backports WILL NOT receive any review |
815 | +## or updates from the Ubuntu security team. |
816 | +deb $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse |
817 | +# deb-src $LB_PARENT_MIRROR_BINARY $LB_DISTRIBUTION-backports main restricted universe multiverse |
818 | + |
819 | +## Uncomment the following two lines to add software from Canonical's |
820 | +## 'partner' repository. |
821 | +## This software is not part of Ubuntu, but is offered by Canonical and the |
822 | +## respective vendors as a service to Ubuntu users. |
823 | +# deb http://archive.canonical.com/ubuntu $LB_DISTRIBUTION partner |
824 | +# deb-src http://archive.canonical.com/ubuntu $LB_DISTRIBUTION partner |
825 | + |
826 | +deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted |
827 | +# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security main restricted |
828 | +deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe |
829 | +# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security universe |
830 | +deb $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse |
831 | +# deb-src $LB_PARENT_MIRROR_BINARY_SECURITY $LB_DISTRIBUTION-security multiverse |
832 | +EOF |
833 | + |
834 | +fi |
835 | +} |
836 | + |
837 | +configure_network_manager() { |
838 | + # If the image pre-installs network-manager, let it manage all devices by |
839 | + # default. Installing NM on an existing system only manages wifi and wwan via |
840 | + # /usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf. When setting |
841 | + # the global backend to NM, netplan overrides that file. |
842 | + if [ -d chroot/usr/lib/NetworkManager ]; then |
843 | + echo "===== Enabling all devices in NetworkManager ====" |
844 | + mkdir -p chroot/etc/netplan |
845 | + cat <<EOF > chroot/etc/netplan/01-network-manager-all.yaml |
846 | +# Let NetworkManager manage all devices on this system |
847 | +network: |
848 | + version: 2 |
849 | + renderer: NetworkManager |
850 | +EOF |
851 | + else |
852 | + echo "==== NetworkManager not installed ====" |
853 | + fi |
854 | +} |
855 | |
856 | === added file 'live-build/lb_binary_layered' |
857 | --- live-build/lb_binary_layered 1970-01-01 00:00:00 +0000 |
858 | +++ live-build/lb_binary_layered 2018-11-28 08:47:44 +0000 |
859 | @@ -0,0 +1,132 @@ |
860 | +#!/bin/sh |
861 | + |
862 | +## live-build(7) - System Build Scripts |
863 | +## Copyright (C) 2006-2012 Daniel Baumann <daniel@debian.org> |
864 | +## |
865 | +## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. |
866 | +## This is free software, and you are welcome to redistribute it |
867 | +## under certain conditions; see COPYING for details. |
868 | + |
869 | + |
870 | +set -e |
871 | + |
872 | +# Including common functions |
873 | +( . "${LIVE_BUILD}/scripts/build.sh" > /dev/null 2>&1 || true ) || . /usr/lib/live/build.sh |
874 | + |
875 | + |
876 | +# Automatically populating config tree |
877 | +if [ -x auto/config ] && [ ! -e .build/config ] |
878 | +then |
879 | + Echo_message "Automatically populating config tree." |
880 | + lb config |
881 | +fi |
882 | + |
883 | +# Setting static variables |
884 | +DESCRIPTION="$(Echo 'build binary images')" |
885 | +HELP="" |
886 | +USAGE="${PROGRAM} [--force]" |
887 | + |
888 | +Arguments "${@}" |
889 | + |
890 | +# Reading configuration files |
891 | +Read_conffiles config/all config/common config/bootstrap config/chroot config/binary config/source |
892 | +Set_defaults |
893 | + |
894 | +# Setup cleanup function |
895 | +Setup_cleanup |
896 | + |
897 | +. config/functions |
898 | + |
899 | +build_layered_squashfs() { |
900 | + local pass=$1 # install|install_subpass|install_subpass_subsubpass|… |
901 | + local prevpass=$2 # install|install_subpass|… |
902 | + local prefix=$3 # 01-|02-|… |
903 | + local lowerlayers=$4 |
904 | + shift 4 # restore ${*} |
905 | + |
906 | + # Cleanup root filesystem |
907 | + lb binary_chroot ${*} |
908 | + |
909 | + # Building squashfs filesystem & manifest |
910 | + base="${PWD}/livecd.${PROJECT}.${prefix}${pass}" |
911 | + squashfs_f="${base}.squashfs" |
912 | + |
913 | + # We have already treated that pass |
914 | + if [ -f "${squashfs_f}" ]; then |
915 | + return |
916 | + fi |
917 | + |
918 | + if [ -n "${lowerlayers}" ]; then |
919 | + mount_overlay ${lowerlayers} "chroot.${pass}/" chroot/ |
920 | + else |
921 | + # first pass |
922 | + rmdir chroot 2>/dev/null||true |
923 | + ln -s "chroot.${pass}/" chroot |
924 | + fi |
925 | + |
926 | + # Full manifest until that PASS |
927 | + squashfs_f_manifest="${base}.manifest" |
928 | + create_manifest "chroot" "${squashfs_f_manifest}.full" |
929 | + |
930 | + # Delta manifest |
931 | + diff -NU0 ${PWD}/livecd.${PROJECT}.[0-9][0-9]-${prevpass}.manifest.full ${squashfs_f_manifest}.full|grep -v ^@ > $squashfs_f_manifest |
932 | + |
933 | + squashfs_f_size="${base}.size" |
934 | + du -B 1 -s "chroot.${pass}/" | cut -f1 > "${squashfs_f_size}" |
935 | + |
936 | + (cd "chroot.${pass}/" && |
937 | + mksquashfs . ${squashfs_f} \ |
938 | + -no-progress -xattrs -comp xz ) |
939 | + |
940 | + if [ -n "${lowerlayers}" ]; then |
941 | + umount chroot |
942 | + else |
943 | + rm chroot |
944 | + mkdir chroot/ |
945 | + fi |
946 | + |
947 | + # Handle direct sublayer of current one |
948 | + # Extract the name of the pass corresponding to the sublayer |
949 | + for subpass in $(ls -d chroot.${pass}_* 2>/dev/null | sed -e "s/chroot\.\(${pass}_[^_]\+\).*/\1/"); do |
950 | + lowerlayers_for_subpass="chroot.${pass}:${lowerlayers}" |
951 | + lowerlayers_for_subpass="${lowerlayers_for_subpass%:}" |
952 | + build_layered_squashfs "${subpass}" "${pass}" "${prefix}" "${lowerlayers_for_subpass}" ${*} |
953 | + done |
954 | +} |
955 | + |
956 | +CURPASS=1 |
957 | +PREVPASS="" |
958 | +PASSPREFIX="" |
959 | +LOWER_LAYERS="" |
960 | +for _PASS in $PASSES |
961 | +do |
962 | + PASSPREFIX="$(printf "%02g" $CURPASS)-" |
963 | + |
964 | + build_layered_squashfs "${_PASS}" "${PREVPASS}" "$PASSPREFIX" "${LOWER_LAYERS}" ${*} |
965 | + |
966 | + LOWER_LAYERS="chroot.${_PASS}:$LOWER_LAYERS" |
967 | + LOWER_LAYERS="${LOWER_LAYERS%:}" |
968 | + PREVPASS=${_PASS} |
969 | + CURPASS=$(( CURPASS + 1 )) |
970 | +done |
971 | + |
972 | +# remount last "main" pass on chroot for lb binary |
973 | +mount_overlay "${LOWER_LAYERS}" "chroot.${_PASS}/" chroot/ |
974 | + |
975 | +# Prepare initrd + kernel |
976 | +lb binary_linux-image ${*} |
977 | + |
978 | +umount chroot/ |
979 | + |
980 | +# Full ISO manifest & size from last main PASS |
981 | +PREFIX="livecd.$PROJECT${SUBARCH:+-$SUBARCH}" |
982 | +cp "livecd.${PROJECT}.${PASSPREFIX}${_PASS}.size" "$PREFIX.size" |
983 | +cp "livecd.${PROJECT}.${PASSPREFIX}${_PASS}.manifest.full" "$PREFIX.manifest" |
984 | + |
985 | +# Ubiquity-compatible removal manifest for ISO not using a layered-aware installer |
986 | +if [ -n "$(ls livecd.${PROJECT}.[0-9][0-9]-live.manifest.full 2>/dev/null)" ] && \ |
987 | + [ -n "$(ls livecd.${PROJECT}.[0-9][0-9]-install.manifest.full 2>/dev/null)" ]; then |
988 | + echo "$(diff livecd.${PROJECT}.[0-9][0-9]-live.manifest.full livecd.${PROJECT}.[0-9][0-9]-install.manifest.full | awk '/^< / { print $2 }')" > livecd.${PROJECT}-manifest-remove |
989 | +fi |
990 | + |
991 | +chmod 644 *.squashfs *.manifest* *.size |
992 | |
993 | === added file 'live-build/lb_chroot_layered' |
994 | --- live-build/lb_chroot_layered 1970-01-01 00:00:00 +0000 |
995 | +++ live-build/lb_chroot_layered 2018-11-28 08:47:44 +0000 |
996 | @@ -0,0 +1,246 @@ |
997 | +#!/bin/sh |
998 | + |
999 | +## live-build(7) - System Build Scripts |
1000 | +## Copyright (C) 2006-2012 Daniel Baumann <daniel@debian.org> |
1001 | +## |
1002 | +## This program comes with ABSOLUTELY NO WARRANTY; for details see COPYING. |
1003 | +## This is free software, and you are welcome to redistribute it |
1004 | +## under certain conditions; see COPYING for details. |
1005 | + |
1006 | +## This is a fork of lb_chroot for layered live system. |
1007 | +## We don't want leaking host configuratino in each layer, and so, |
1008 | +## we clean and setup the chroot each time. |
1009 | +## In addition, we create the squashfs for each layer, but top one (live) |
1010 | +## which still can be configured after lb chroot call. |
1011 | + |
1012 | +set -e |
1013 | + |
1014 | +# Including common functions |
1015 | +( . "${LIVE_BUILD}/scripts/build.sh" > /dev/null 2>&1 || true ) || . /usr/lib/live/build.sh |
1016 | + |
1017 | +# Automatically populating config tree |
1018 | +if [ -x auto/config ] && [ ! -e .build/config ] |
1019 | +then |
1020 | + Echo_message "Automatically populating config tree." |
1021 | + lb config |
1022 | +fi |
1023 | + |
1024 | +# Setting static variables |
1025 | +DESCRIPTION="$(Echo 'customize the Debian system')" |
1026 | +HELP="" |
1027 | +USAGE="${PROGRAM} [--force]" |
1028 | + |
1029 | +Arguments "${@}" |
1030 | + |
1031 | +# Reading configuration files |
1032 | +Read_conffiles config/all config/common config/bootstrap config/chroot config/binary config/source |
1033 | +Set_defaults |
1034 | + |
1035 | +# Setup cleanup function |
1036 | +Setup_cleanup |
1037 | + |
1038 | +. config/functions |
1039 | + |
1040 | +lb_chroot_remove_packages() { |
1041 | + # Remove packages from the chroot specific to this layer |
1042 | + # |
1043 | + # $1: Name of the pass* |
1044 | + local pass=$1 |
1045 | + |
1046 | + Expand_packagelist "$(basename config/package-lists/*.removal-list.chroot_${pass})" "config/package-lists" \ |
1047 | + >> chroot/root/packages.chroot.removal |
1048 | + Chroot chroot "xargs --arg-file=/root/packages.chroot.removal apt-get ${APT_OPTIONS} autoremove --purge" |
1049 | + rm -f chroot/root/packages.chroot.removal |
1050 | +} |
1051 | + |
1052 | +# Create the snap list specific to this layer |
1053 | +lb_chroot_snap_lists() { |
1054 | + local pass=$1 |
1055 | + local prevpass=$2 |
1056 | + |
1057 | + # This assumes that the prefix is unique for a given project |
1058 | + local snap_for_pass=$(ls config/package-lists/*.snaplist.chroot_${pass}.full 2>/dev/null || true) |
1059 | + local snap_for_prevpass=$(ls config/package-lists/*.snaplist.chroot_${prevpass}.full 2>/dev/null || true) |
1060 | + |
1061 | + if [ -z "${snap_for_pass}" ]; then |
1062 | + return |
1063 | + fi |
1064 | + |
1065 | + if [ -z "${snap_for_prevpass}" ]; then |
1066 | + cp ${snap_for_pass} ${snap_for_pass%.full} |
1067 | + return |
1068 | + fi |
1069 | + |
1070 | + # Generate a list of snaps added to a layer. |
1071 | + diff -NU0 ${snap_for_prevpass} ${snap_for_pass}|grep -Ev '^(---|\+\+\+|@@)'|cut -c2- > ${snap_for_pass%.full} |
1072 | +} |
1073 | + |
1074 | +lb_chroot_install_snaps() { |
1075 | + # Prepare the snap environment and install snaps into a chroot |
1076 | + # |
1077 | + # $1: Name of the pass |
1078 | + |
1079 | + local snaplist_file=$(ls config/package-lists/*.snaplist.chroot_${1} 2>/dev/null || true) |
1080 | + |
1081 | + if [ -z "${snaplist_file}" ]; then |
1082 | + return |
1083 | + fi |
1084 | + |
1085 | + snap_prepare chroot |
1086 | + |
1087 | + while read snap; do |
1088 | + snap_preseed chroot "${snap}" |
1089 | + done < $snaplist_file |
1090 | +} |
1091 | + |
1092 | +lb_chroot_includes() { |
1093 | + # Copying includes from pass subdirectory |
1094 | + local pass="$1" |
1095 | + |
1096 | + if [ ! -d config/includes.chroot.${pass} ]; then |
1097 | + return |
1098 | + fi |
1099 | + |
1100 | + cd config/includes.chroot.${pass} |
1101 | + find . | cpio -dmpu --no-preserve-owner "${OLDPWD}"/chroot |
1102 | + cd "${OLDPWD}" |
1103 | +} |
1104 | + |
1105 | +create_chroot_pass() { |
1106 | + local pass=$1 |
1107 | + local prevpass=$2 |
1108 | + local lowerlayers=$3 |
1109 | + local passtype=$4 # "first"|"last"|"" empty string |
1110 | + shift 4 # restore ${*} |
1111 | + |
1112 | + # We have already treated that pass |
1113 | + if [ -d "chroot.${pass}/" ]; then |
1114 | + return |
1115 | + fi |
1116 | + |
1117 | + export PASS=${pass} |
1118 | + |
1119 | + if [ "${passtype}" != "first" ]; then |
1120 | + mkdir chroot.${pass} |
1121 | + mount_overlay ${lowerlayers} "chroot.${pass}/" chroot/ |
1122 | + fi |
1123 | + |
1124 | + # Configuring chroot |
1125 | + lb chroot_cache restore ${*} |
1126 | + lb chroot_devpts install ${*} |
1127 | + lb chroot_proc install ${*} |
1128 | + lb chroot_sysfs install ${*} |
1129 | + lb chroot_debianchroot install ${*} |
1130 | + lb chroot_dpkg install ${*} |
1131 | + lb chroot_tmpfs install ${*} |
1132 | + lb chroot_hosts install ${*} |
1133 | + lb chroot_resolv install ${*} |
1134 | + lb chroot_hostname install ${*} |
1135 | + lb chroot_apt install ${*} |
1136 | + # Note: this triggers an upgrade + dist-ugprade; which may impact sublayers with more |
1137 | + # diff content than desired. However, we still need to setup the archive and teardown |
1138 | + # for each layer. |
1139 | + # We could modify livebuild if necessary to have conditional upgrade (first pass only). |
1140 | + lb chroot_archives chroot install ${*} |
1141 | + |
1142 | + if [ "${passtype}" = "first" ]; then |
1143 | + configure_universe |
1144 | + fi |
1145 | + |
1146 | + # Customizing chroot |
1147 | + lb chroot_linux-image ${*} |
1148 | + lb chroot_preseed ${*} |
1149 | + lb chroot_early_hooks ${*} |
1150 | + |
1151 | + lb chroot_package-lists ${pass} ${*} |
1152 | + lb chroot_install-packages ${pass} ${*} |
1153 | + lb_chroot_remove_packages ${pass} ${*} |
1154 | + |
1155 | + # Snap management |
1156 | + lb_chroot_snap_lists ${pass} ${prevpass} |
1157 | + lb_chroot_install_snaps ${pass} ${*} |
1158 | + |
1159 | + # Kernel should be in first layer |
1160 | + if [ "${passtype}" = "first" ]; then |
1161 | + configure_network_manager |
1162 | + Chroot chroot "dpkg -l linux-headers-3* linux-headers-4*" 2>/dev/null \ |
1163 | + | awk '/^i/ {print $2}' > chroot.headers |
1164 | + for i in $(cat chroot.headers); do |
1165 | + Chroot chroot "apt-mark auto $i" |
1166 | + done |
1167 | + fi |
1168 | + |
1169 | + Chroot chroot "apt-get --purge -y autoremove" |
1170 | + |
1171 | + # Add live packages to top layer |
1172 | + if [ "${passtype}" = "last" ]; then |
1173 | + lb chroot_live-packages ${*} |
1174 | + fi |
1175 | + |
1176 | + # Run includes by pass |
1177 | + lb_chroot_includes ${pass} ${*} |
1178 | + |
1179 | + lb chroot_hooks ${*} |
1180 | + lb chroot_hacks ${*} |
1181 | + lb chroot_interactive ${*} |
1182 | + |
1183 | + # Misc ubuntu cleanup and post-layer configuration |
1184 | + clean_debian_chroot |
1185 | + /usr/share/livecd-rootfs/minimize-manual chroot |
1186 | + |
1187 | + Chroot chroot "dpkg-query -W" > chroot.packages.${pass} |
1188 | + |
1189 | + # Deconfiguring chroot |
1190 | + lb chroot_archives chroot remove ${*} |
1191 | + lb chroot_apt remove ${*} |
1192 | + lb chroot_hostname remove ${*} |
1193 | + lb chroot_resolv remove ${*} |
1194 | + lb chroot_hosts remove ${*} |
1195 | + lb chroot_tmpfs remove ${*} |
1196 | + lb chroot_dpkg remove ${*} |
1197 | + lb chroot_debianchroot remove ${*} |
1198 | + lb chroot_sysfs remove ${*} |
1199 | + lb chroot_proc remove ${*} |
1200 | + lb chroot_devpts remove ${*} |
1201 | + lb chroot_cache save ${*} |
1202 | + |
1203 | + if [ "${passtype}" = "first" ]; then |
1204 | + mv chroot chroot.${pass} |
1205 | + mkdir chroot |
1206 | + else |
1207 | + umount chroot |
1208 | + fi |
1209 | + |
1210 | + # Handle direct sublayer of current one |
1211 | + # Extract the name of the pass corresponding to the sublayer |
1212 | + for subpass in $(ls config/package-lists/*list.chroot_${pass}_* 2>/dev/null | sed -e "s/.*list\.chroot_\(${pass}_[^_]\+\).*/\1/"); do |
1213 | + lowerlayers_for_subpass="chroot.${pass}:${lowerlayers}" |
1214 | + lowerlayers_for_subpass="${lowerlayers_for_subpass%:}" |
1215 | + create_chroot_pass "${subpass}" "${pass}" "${lowerlayers_for_subpass}" "" ${*} |
1216 | + done |
1217 | +} |
1218 | + |
1219 | +PASSES="${PASSES:-install live}" |
1220 | +CURPASS=1 |
1221 | +PREVPASS="" |
1222 | +LASTPASS=$(echo $PASSES|wc -w) |
1223 | +LOWER_LAYERS="" |
1224 | +for _PASS in $PASSES |
1225 | +do |
1226 | + PASSTYPE="" |
1227 | + if [ $CURPASS -eq 1 ]; then |
1228 | + PASSTYPE="first" |
1229 | + elif [ $CURPASS -eq $LASTPASS ]; then |
1230 | + PASSTYPE="last" |
1231 | + fi |
1232 | + |
1233 | + create_chroot_pass "$_PASS" "$PREVPASS" "$LOWER_LAYERS" "$PASSTYPE" ${*} |
1234 | + |
1235 | + LOWER_LAYERS="chroot.${_PASS}:$LOWER_LAYERS" |
1236 | + LOWER_LAYERS="${LOWER_LAYERS%:}" |
1237 | + PREVPASS=${_PASS} |
1238 | + |
1239 | + CURPASS=$(( CURPASS + 1 )) |
1240 | +done |
1241 | + |
1242 | +rmdir chroot |
In passes, how does one specify multiple branches of stacks? Or is only a linear stack allowed by this code?
Cause the current subiquity images do not have `live` as the top of the stack.... They do this:
+--> Base +-----> Live
|
+-----> Rack +---> Region
Because I am expecting to have the ability to somehow specify what each pass depends on. But it looks like the base for a subsequent pass, is always the previous one?!
It would be nice to extend PASS syntax to optionally accept an arbitrary `base`, e.g.
PASSES="base rack region base:live" to encode the above graph, and such that `base:live` pass uses base as the lowerdir, instead of region (i.e. the previous pass result).
Or something...
not sure if : is acceptable pair delimiter here, or not.
Also not sure if we want to always enforce specifying `base` such that we can construct multiple root nodes in one go. E.g. `base base:rack rack:region base:live` or `:base rack region base:live` for the above graph.
Or like maybe always list all layers?! but that violates donot-repeat- yourself principle... E.g. `base base:rack base:rack:region base:live`
===
When calling includes/hooks are they aware which pass they are for? what is the source dir for each pass, for e.g. binary.includes? I'm guessing that PASS variable is set, but not sure.
===
filesystem.squashfs is somewhat is a special name, so it would be nice to keep that as the base one. And also possibly adjust logic in casper as to what it mounts by default.... cause e.g. i think i hide maas squashfes in a subdir, to prevent casper from mounting those, which is kind of a hack. I wonder if we do need to write out the valid stacks (passes?!), which casper can then use to boot to whichever stack is valid. With subiquity image this could then result in "Live Server, Live MAAS Rack, Live MAAS Region, Live Server with Installer" boot options. As example, for better or worse.
====
No idea if SUBPROJECT and IMAGE_FORMAT are the right things to extend for this..... and if they are easily extendable like this in launchpad livefs builders & ubuntu-cdimage codes.
Cause I can see the potential for using layers in SUBPROJECT= minimized, if for example, cpc builds are converted to layers they would have full and minimized layered builds.... and SUBPROJECT= minimized- layered sounds ugly =)
====
manifest diffs for layers is nice; cause in cpc we have struggled to consitently represent manifests / changelogs of "it's just like that image, but has this stuff on it"
====
packaging layers as actual static filesystems might be interesting, but i guess hooks will be able to do that anyway.
====
Overall, this looks ok, and shouldn't break any existing stuff - as long as we can clear the top level new extensions of
SUBPROJECT= layered live-layered
IMAGEFORMAT=
and that needs like an architect review.