xref: /OK3568_Linux_fs/yocto/poky/meta/lib/oeqa/selftest/cases/overlayfs.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#
2*4882a593Smuzhiyun# SPDX-License-Identifier: MIT
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun
5*4882a593Smuzhiyunfrom oeqa.selftest.case import OESelftestTestCase
6*4882a593Smuzhiyunfrom oeqa.utils.commands import bitbake, runqemu
7*4882a593Smuzhiyunfrom oeqa.core.decorator import OETestTag
8*4882a593Smuzhiyun
9*4882a593Smuzhiyundef getline_qemu(out, line):
10*4882a593Smuzhiyun    for l in out.split('\n'):
11*4882a593Smuzhiyun        if line in l:
12*4882a593Smuzhiyun            return l
13*4882a593Smuzhiyun
14*4882a593Smuzhiyundef getline(res, line):
15*4882a593Smuzhiyun    return getline_qemu(res.output, line)
16*4882a593Smuzhiyun
17*4882a593Smuzhiyunclass OverlayFSTests(OESelftestTestCase):
18*4882a593Smuzhiyun    """Overlayfs class usage tests"""
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun    def add_overlay_conf_to_machine(self):
21*4882a593Smuzhiyun        machine_inc = """
22*4882a593SmuzhiyunOVERLAYFS_MOUNT_POINT[mnt-overlay] = "/mnt/overlay"
23*4882a593Smuzhiyun"""
24*4882a593Smuzhiyun        self.set_machine_config(machine_inc)
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun    def test_distro_features_missing(self):
27*4882a593Smuzhiyun        """
28*4882a593Smuzhiyun        Summary:   Check that required DISTRO_FEATURES are set
29*4882a593Smuzhiyun        Expected:  Fail when either systemd or overlayfs are not in DISTRO_FEATURES
30*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
31*4882a593Smuzhiyun        """
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun        config = """
34*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user"
35*4882a593Smuzhiyun"""
36*4882a593Smuzhiyun        overlayfs_recipe_append = """
37*4882a593Smuzhiyuninherit overlayfs
38*4882a593Smuzhiyun"""
39*4882a593Smuzhiyun        self.write_config(config)
40*4882a593Smuzhiyun        self.add_overlay_conf_to_machine()
41*4882a593Smuzhiyun        self.write_recipeinc('overlayfs-user', overlayfs_recipe_append)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
44*4882a593Smuzhiyun        line = getline(res, "overlayfs-user was skipped: missing required distro features")
45*4882a593Smuzhiyun        self.assertTrue("overlayfs" in res.output, msg=res.output)
46*4882a593Smuzhiyun        self.assertTrue("systemd" in res.output, msg=res.output)
47*4882a593Smuzhiyun        self.assertTrue("ERROR: Required build target 'core-image-minimal' has no buildable providers." in res.output, msg=res.output)
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun    def test_not_all_units_installed(self):
50*4882a593Smuzhiyun        """
51*4882a593Smuzhiyun        Summary:   Test QA check that we have required mount units in the image
52*4882a593Smuzhiyun        Expected:  Fail because mount unit for overlay partition is not installed
53*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
54*4882a593Smuzhiyun        """
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun        config = """
57*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user"
58*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd overlayfs"
59*4882a593Smuzhiyun"""
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun        self.write_config(config)
62*4882a593Smuzhiyun        self.add_overlay_conf_to_machine()
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
65*4882a593Smuzhiyun        line = getline(res, " Mount path /mnt/overlay not found in fstab and unit mnt-overlay.mount not found in systemd unit directories")
66*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("WARNING:"), msg=res.output)
67*4882a593Smuzhiyun        line = getline(res, "Not all mount paths and units are installed in the image")
68*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("ERROR:"), msg=res.output)
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun    def test_not_all_units_installed_but_qa_skipped(self):
71*4882a593Smuzhiyun        """
72*4882a593Smuzhiyun        Summary:   Test skipping the QA check
73*4882a593Smuzhiyun        Expected:  Image is created successfully
74*4882a593Smuzhiyun        Author:    Claudius Heine <ch@denx.de>
75*4882a593Smuzhiyun        """
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun        config = """
78*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user"
79*4882a593SmuzhiyunDISTRO_FEATURES += "systemd overlayfs"
80*4882a593SmuzhiyunOVERLAYFS_QA_SKIP[mnt-overlay] = "mount-configured"
81*4882a593Smuzhiyun"""
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun        self.write_config(config)
84*4882a593Smuzhiyun        self.add_overlay_conf_to_machine()
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun        bitbake('core-image-minimal')
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun    def test_mount_unit_not_set(self):
89*4882a593Smuzhiyun        """
90*4882a593Smuzhiyun        Summary:   Test whether mount unit was set properly
91*4882a593Smuzhiyun        Expected:  Fail because mount unit was not set
92*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
93*4882a593Smuzhiyun        """
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun        config = """
96*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user"
97*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd overlayfs"
98*4882a593Smuzhiyun"""
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun        self.write_config(config)
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
103*4882a593Smuzhiyun        line = getline(res, "A recipe uses overlayfs class but there is no OVERLAYFS_MOUNT_POINT set in your MACHINE configuration")
104*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun    def test_wrong_mount_unit_set(self):
107*4882a593Smuzhiyun        """
108*4882a593Smuzhiyun        Summary:   Test whether mount unit was set properly
109*4882a593Smuzhiyun        Expected:  Fail because not the correct flag used for mount unit
110*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
111*4882a593Smuzhiyun        """
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun        config = """
114*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user"
115*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd overlayfs"
116*4882a593Smuzhiyun"""
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun        wrong_machine_config = """
119*4882a593SmuzhiyunOVERLAYFS_MOUNT_POINT[usr-share-overlay] = "/usr/share/overlay"
120*4882a593Smuzhiyun"""
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun        self.write_config(config)
123*4882a593Smuzhiyun        self.set_machine_config(wrong_machine_config)
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
126*4882a593Smuzhiyun        line = getline(res, "Missing required mount point for OVERLAYFS_MOUNT_POINT[mnt-overlay] in your MACHINE configuration")
127*4882a593Smuzhiyun        self.assertTrue(line and line.startswith("Parsing recipes...ERROR:"), msg=res.output)
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun    def _test_correct_image(self, recipe, data):
130*4882a593Smuzhiyun        """
131*4882a593Smuzhiyun        Summary:   Check that we can create an image when all parameters are
132*4882a593Smuzhiyun                   set correctly
133*4882a593Smuzhiyun        Expected:  Image is created successfully
134*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
135*4882a593Smuzhiyun        """
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun        config = """
138*4882a593SmuzhiyunIMAGE_INSTALL:append = " overlayfs-user systemd-machine-units"
139*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd overlayfs"
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun# Use systemd as init manager
142*4882a593SmuzhiyunVIRTUAL-RUNTIME_init_manager = "systemd"
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun# enable overlayfs in the kernel
145*4882a593SmuzhiyunKERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
146*4882a593Smuzhiyun"""
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun        overlayfs_recipe_append = """
149*4882a593SmuzhiyunOVERLAYFS_WRITABLE_PATHS[mnt-overlay] += "/usr/share/another-overlay-mount"
150*4882a593Smuzhiyun
151*4882a593SmuzhiyunSYSTEMD_SERVICE:${PN} += " \
152*4882a593Smuzhiyun    my-application.service \
153*4882a593Smuzhiyun"
154*4882a593Smuzhiyun
155*4882a593Smuzhiyundo_install:append() {
156*4882a593Smuzhiyun    install -d ${D}${systemd_system_unitdir}
157*4882a593Smuzhiyun    cat <<EOT > ${D}${systemd_system_unitdir}/my-application.service
158*4882a593Smuzhiyun[Unit]
159*4882a593SmuzhiyunDescription=Sample application start-up unit
160*4882a593SmuzhiyunAfter=overlayfs-user-overlays.service
161*4882a593SmuzhiyunRequires=overlayfs-user-overlays.service
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun[Service]
164*4882a593SmuzhiyunType=oneshot
165*4882a593SmuzhiyunExecStart=/bin/true
166*4882a593SmuzhiyunRemainAfterExit=true
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun[Install]
169*4882a593SmuzhiyunWantedBy=multi-user.target
170*4882a593SmuzhiyunEOT
171*4882a593Smuzhiyun}
172*4882a593Smuzhiyun"""
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun        self.write_config(config)
175*4882a593Smuzhiyun        self.add_overlay_conf_to_machine()
176*4882a593Smuzhiyun        self.write_recipeinc(recipe, data)
177*4882a593Smuzhiyun        self.write_recipeinc('overlayfs-user', overlayfs_recipe_append)
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun        bitbake('core-image-minimal')
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun        with runqemu('core-image-minimal') as qemu:
182*4882a593Smuzhiyun            # Check that application service started
183*4882a593Smuzhiyun            status, output = qemu.run_serial("systemctl status my-application")
184*4882a593Smuzhiyun            self.assertTrue("active (exited)" in output, msg=output)
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun            # Check that overlay mounts are dependencies of our application unit
187*4882a593Smuzhiyun            status, output = qemu.run_serial("systemctl list-dependencies my-application")
188*4882a593Smuzhiyun            self.assertTrue("overlayfs-user-overlays.service" in output, msg=output)
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun            status, output = qemu.run_serial("systemctl list-dependencies overlayfs-user-overlays")
191*4882a593Smuzhiyun            self.assertTrue("usr-share-another\\x2doverlay\\x2dmount.mount" in output, msg=output)
192*4882a593Smuzhiyun            self.assertTrue("usr-share-my\\x2dapplication.mount" in output, msg=output)
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun            # Check that we have /mnt/overlay fs mounted as tmpfs and
195*4882a593Smuzhiyun            # /usr/share/my-application as an overlay (see overlayfs-user recipe)
196*4882a593Smuzhiyun            status, output = qemu.run_serial("/bin/mount -t tmpfs,overlay")
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun            line = getline_qemu(output, "on /mnt/overlay")
199*4882a593Smuzhiyun            self.assertTrue(line and line.startswith("tmpfs"), msg=output)
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun            line = getline_qemu(output, "upperdir=/mnt/overlay/upper/usr/share/my-application")
202*4882a593Smuzhiyun            self.assertTrue(line and line.startswith("overlay"), msg=output)
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun            line = getline_qemu(output, "upperdir=/mnt/overlay/upper/usr/share/another-overlay-mount")
205*4882a593Smuzhiyun            self.assertTrue(line and line.startswith("overlay"), msg=output)
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun    @OETestTag("runqemu")
208*4882a593Smuzhiyun    def test_correct_image_fstab(self):
209*4882a593Smuzhiyun        """
210*4882a593Smuzhiyun        Summary:   Check that we can create an image when all parameters are
211*4882a593Smuzhiyun                   set correctly via fstab
212*4882a593Smuzhiyun        Expected:  Image is created successfully
213*4882a593Smuzhiyun        Author:    Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
214*4882a593Smuzhiyun        """
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun        base_files_append = """
217*4882a593Smuzhiyundo_install:append() {
218*4882a593Smuzhiyun    cat <<EOT >> ${D}${sysconfdir}/fstab
219*4882a593Smuzhiyuntmpfs                /mnt/overlay         tmpfs      mode=1777,strictatime,nosuid,nodev  0  0
220*4882a593SmuzhiyunEOT
221*4882a593Smuzhiyun}
222*4882a593Smuzhiyun"""
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun        self._test_correct_image('base-files', base_files_append)
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun    @OETestTag("runqemu")
227*4882a593Smuzhiyun    def test_correct_image_unit(self):
228*4882a593Smuzhiyun        """
229*4882a593Smuzhiyun        Summary:   Check that we can create an image when all parameters are
230*4882a593Smuzhiyun                   set correctly via mount unit
231*4882a593Smuzhiyun        Expected:  Image is created successfully
232*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
233*4882a593Smuzhiyun        """
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun        systemd_machine_unit_append = """
236*4882a593SmuzhiyunSYSTEMD_SERVICE:${PN} += " \
237*4882a593Smuzhiyun    mnt-overlay.mount \
238*4882a593Smuzhiyun"
239*4882a593Smuzhiyun
240*4882a593Smuzhiyundo_install:append() {
241*4882a593Smuzhiyun    install -d ${D}${systemd_system_unitdir}
242*4882a593Smuzhiyun    cat <<EOT > ${D}${systemd_system_unitdir}/mnt-overlay.mount
243*4882a593Smuzhiyun[Unit]
244*4882a593SmuzhiyunDescription=Tmpfs directory
245*4882a593SmuzhiyunDefaultDependencies=no
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun[Mount]
248*4882a593SmuzhiyunWhat=tmpfs
249*4882a593SmuzhiyunWhere=/mnt/overlay
250*4882a593SmuzhiyunType=tmpfs
251*4882a593SmuzhiyunOptions=mode=1777,strictatime,nosuid,nodev
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun[Install]
254*4882a593SmuzhiyunWantedBy=multi-user.target
255*4882a593SmuzhiyunEOT
256*4882a593Smuzhiyun}
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun"""
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun        self._test_correct_image('systemd-machine-units', systemd_machine_unit_append)
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun@OETestTag("runqemu")
263*4882a593Smuzhiyunclass OverlayFSEtcRunTimeTests(OESelftestTestCase):
264*4882a593Smuzhiyun    """overlayfs-etc class tests"""
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun    def test_all_required_variables_set(self):
267*4882a593Smuzhiyun        """
268*4882a593Smuzhiyun        Summary:   Check that required variables are set
269*4882a593Smuzhiyun        Expected:  Fail when any of required variables is missing
270*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
271*4882a593Smuzhiyun        """
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun        configBase = """
274*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd"
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun# Use systemd as init manager
277*4882a593SmuzhiyunVIRTUAL-RUNTIME_init_manager = "systemd"
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun# enable overlayfs in the kernel
280*4882a593SmuzhiyunKERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun# Image configuration for overlayfs-etc
283*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "overlayfs-etc"
284*4882a593SmuzhiyunIMAGE_FEATURES:remove = "package-management"
285*4882a593Smuzhiyun"""
286*4882a593Smuzhiyun        configMountPoint = """
287*4882a593SmuzhiyunOVERLAYFS_ETC_MOUNT_POINT = "/data"
288*4882a593Smuzhiyun"""
289*4882a593Smuzhiyun        configDevice = """
290*4882a593SmuzhiyunOVERLAYFS_ETC_DEVICE = "/dev/mmcblk0p1"
291*4882a593Smuzhiyun"""
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun        self.write_config(configBase)
294*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
295*4882a593Smuzhiyun        line = getline(res, "OVERLAYFS_ETC_MOUNT_POINT must be set in your MACHINE configuration")
296*4882a593Smuzhiyun        self.assertTrue(line, msg=res.output)
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun        self.append_config(configMountPoint)
299*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
300*4882a593Smuzhiyun        line = getline(res, "OVERLAYFS_ETC_DEVICE must be set in your MACHINE configuration")
301*4882a593Smuzhiyun        self.assertTrue(line, msg=res.output)
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun        self.append_config(configDevice)
304*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
305*4882a593Smuzhiyun        line = getline(res, "OVERLAYFS_ETC_FSTYPE should contain a valid file system type on /dev/mmcblk0p1")
306*4882a593Smuzhiyun        self.assertTrue(line, msg=res.output)
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun    def test_image_feature_conflict(self):
309*4882a593Smuzhiyun        """
310*4882a593Smuzhiyun        Summary:   Overlayfs-etc is not allowed to be used with package-management
311*4882a593Smuzhiyun        Expected:  Feature conflict
312*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
313*4882a593Smuzhiyun        """
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun        config = """
316*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd"
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun# Use systemd as init manager
319*4882a593SmuzhiyunVIRTUAL-RUNTIME_init_manager = "systemd"
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun# enable overlayfs in the kernel
322*4882a593SmuzhiyunKERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
323*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "overlayfs-etc"
324*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "package-management"
325*4882a593Smuzhiyun"""
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun        self.write_config(config)
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun        res = bitbake('core-image-minimal', ignore_status=True)
330*4882a593Smuzhiyun        line = getline(res, "contains conflicting IMAGE_FEATURES")
331*4882a593Smuzhiyun        self.assertTrue("overlayfs-etc" in res.output, msg=res.output)
332*4882a593Smuzhiyun        self.assertTrue("package-management" in res.output, msg=res.output)
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun    def test_image_feature_is_missing_class_included(self):
335*4882a593Smuzhiyun        configAppend = """
336*4882a593SmuzhiyunINHERIT += "overlayfs-etc"
337*4882a593Smuzhiyun"""
338*4882a593Smuzhiyun        self.run_check_image_feature(configAppend)
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun    def test_image_feature_is_missing(self):
341*4882a593Smuzhiyun        self.run_check_image_feature()
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun    def run_check_image_feature(self, appendToConfig=""):
344*4882a593Smuzhiyun        """
345*4882a593Smuzhiyun        Summary:   Overlayfs-etc class is not applied when image feature is not set
346*4882a593Smuzhiyun                   even if we inherit it directly,
347*4882a593Smuzhiyun        Expected:  Image is created successfully but /etc is not an overlay
348*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
349*4882a593Smuzhiyun        """
350*4882a593Smuzhiyun
351*4882a593Smuzhiyun        config = f"""
352*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd"
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun# Use systemd as init manager
355*4882a593SmuzhiyunVIRTUAL-RUNTIME_init_manager = "systemd"
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun# enable overlayfs in the kernel
358*4882a593SmuzhiyunKERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
359*4882a593Smuzhiyun
360*4882a593SmuzhiyunIMAGE_FSTYPES += "wic"
361*4882a593SmuzhiyunWKS_FILE = "overlayfs_etc.wks.in"
362*4882a593Smuzhiyun
363*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "read-only-rootfs"
364*4882a593Smuzhiyun# Image configuration for overlayfs-etc
365*4882a593SmuzhiyunOVERLAYFS_ETC_MOUNT_POINT = "/data"
366*4882a593SmuzhiyunOVERLAYFS_ETC_DEVICE = "/dev/sda3"
367*4882a593Smuzhiyun{appendToConfig}
368*4882a593Smuzhiyun"""
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun        self.write_config(config)
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun        bitbake('core-image-minimal')
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun        with runqemu('core-image-minimal', image_fstype='wic') as qemu:
375*4882a593Smuzhiyun            status, output = qemu.run_serial("/bin/mount")
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun            line = getline_qemu(output, "upperdir=/data/overlay-etc/upper")
378*4882a593Smuzhiyun            self.assertFalse(line, msg=output)
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun    def test_sbin_init_preinit(self):
381*4882a593Smuzhiyun        self.run_sbin_init(False)
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun    def test_sbin_init_original(self):
384*4882a593Smuzhiyun        self.run_sbin_init(True)
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun    def run_sbin_init(self, origInit):
387*4882a593Smuzhiyun        """
388*4882a593Smuzhiyun        Summary:   Confirm we can replace original init and mount overlay on top of /etc
389*4882a593Smuzhiyun        Expected:  Image is created successfully and /etc is mounted as an overlay
390*4882a593Smuzhiyun        Author:    Vyacheslav Yurkov <uvv.mail@gmail.com>
391*4882a593Smuzhiyun        """
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun        config = """
394*4882a593SmuzhiyunDISTRO_FEATURES:append = " systemd"
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun# Use systemd as init manager
397*4882a593SmuzhiyunVIRTUAL-RUNTIME_init_manager = "systemd"
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun# enable overlayfs in the kernel
400*4882a593SmuzhiyunKERNEL_EXTRA_FEATURES:append = " features/overlayfs/overlayfs.scc"
401*4882a593Smuzhiyun
402*4882a593SmuzhiyunIMAGE_FSTYPES += "wic"
403*4882a593SmuzhiyunOVERLAYFS_INIT_OPTION = "{OVERLAYFS_INIT_OPTION}"
404*4882a593SmuzhiyunWKS_FILE = "overlayfs_etc.wks.in"
405*4882a593Smuzhiyun
406*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "read-only-rootfs"
407*4882a593Smuzhiyun# Image configuration for overlayfs-etc
408*4882a593SmuzhiyunEXTRA_IMAGE_FEATURES += "overlayfs-etc"
409*4882a593SmuzhiyunIMAGE_FEATURES:remove = "package-management"
410*4882a593SmuzhiyunOVERLAYFS_ETC_MOUNT_POINT = "/data"
411*4882a593SmuzhiyunOVERLAYFS_ETC_FSTYPE = "ext4"
412*4882a593SmuzhiyunOVERLAYFS_ETC_DEVICE = "/dev/sda3"
413*4882a593SmuzhiyunOVERLAYFS_ETC_USE_ORIG_INIT_NAME = "{OVERLAYFS_ETC_USE_ORIG_INIT_NAME}"
414*4882a593Smuzhiyun"""
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun        args = {
417*4882a593Smuzhiyun            'OVERLAYFS_INIT_OPTION': "" if origInit else "init=/sbin/preinit",
418*4882a593Smuzhiyun            'OVERLAYFS_ETC_USE_ORIG_INIT_NAME': int(origInit == True)
419*4882a593Smuzhiyun        }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun        self.write_config(config.format(**args))
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun        bitbake('core-image-minimal')
424*4882a593Smuzhiyun        testFile = "/etc/my-test-data"
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun        with runqemu('core-image-minimal', image_fstype='wic', discard_writes=False) as qemu:
427*4882a593Smuzhiyun            status, output = qemu.run_serial("/bin/mount")
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun            line = getline_qemu(output, "/dev/sda3")
430*4882a593Smuzhiyun            self.assertTrue("/data" in output, msg=output)
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun            line = getline_qemu(output, "upperdir=/data/overlay-etc/upper")
433*4882a593Smuzhiyun            self.assertTrue(line and line.startswith("/data/overlay-etc/upper on /etc type overlay"), msg=output)
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun            status, output = qemu.run_serial("touch " + testFile)
436*4882a593Smuzhiyun            status, output = qemu.run_serial("sync")
437*4882a593Smuzhiyun            status, output = qemu.run_serial("ls -1 " + testFile)
438*4882a593Smuzhiyun            line = getline_qemu(output, testFile)
439*4882a593Smuzhiyun            self.assertTrue(line and line.startswith(testFile), msg=output)
440*4882a593Smuzhiyun
441*4882a593Smuzhiyun        # Check that file exists in /etc after reboot
442*4882a593Smuzhiyun        with runqemu('core-image-minimal', image_fstype='wic') as qemu:
443*4882a593Smuzhiyun            status, output = qemu.run_serial("ls -1 " + testFile)
444*4882a593Smuzhiyun            line = getline_qemu(output, testFile)
445*4882a593Smuzhiyun            self.assertTrue(line and line.startswith(testFile), msg=output)
446