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