Esempio n. 1
0
def test_append_overlays_run(mocker):
    params = {
        "format": "cpio.newc",
        "overlays": {
            "modules": {
                "url": "http://example.com/modules.tar.xz",
                "compression": "xz",
                "format": "tar",
                "path": "/",
            }
        },
    }
    action = AppendOverlays("rootfs", params)
    action.update_cpio = mocker.stub()
    action.update_guestfs = mocker.stub()
    action.update_tar = mocker.stub()
    assert action.run(None, 0) is None
    action.update_cpio.assert_called_once_with()

    params["format"] = "ext4"
    assert action.run(None, 0) is None
    action.update_guestfs.assert_called_once_with()

    params["format"] = "tar"
    assert action.run(None, 0) is None
    action.update_tar.assert_called_once_with()
Esempio n. 2
0
def test_append_lava_overlay_update_cpio(caplog, mocker, tmpdir):
    caplog.set_level(logging.DEBUG)
    params = {"format": "cpio.newc", "overlays": {"lava": True}}

    action = AppendOverlays("rootfs", params)
    action.job = Job(1234, {}, None)
    action.parameters = {
        "rootfs": {"url": "http://example.com/rootfs.cpio.gz", **params},
        "namespace": "common",
    }
    action.data = {
        "common": {
            "compress-overlay": {"output": {"file": str(tmpdir / "overlay.tar.gz")}},
            "download-action": {
                "rootfs": {
                    "file": str(tmpdir / "rootfs.cpio.gz"),
                    "compression": "gz",
                    "decompressed": False,
                }
            },
        }
    }
    action.mkdtemp = lambda: str(tmpdir)
    decompress_file = mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.decompress_file"
    )
    uncpio = mocker.patch("lava_dispatcher.actions.deploy.apply_overlay.uncpio")
    unlink = mocker.patch("os.unlink")
    untar_file = mocker.patch("lava_dispatcher.actions.deploy.apply_overlay.untar_file")
    cpio = mocker.patch("lava_dispatcher.actions.deploy.apply_overlay.cpio")
    compress_file = mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.compress_file"
    )

    action.update_cpio()

    decompress_file.assert_called_once_with(str(tmpdir / "rootfs.cpio.gz"), "gz")
    uncpio.assert_called_once_with(decompress_file(), str(tmpdir))
    unlink.assert_called_once_with(decompress_file())
    untar_file.assert_called_once_with(
        str(tmpdir / "overlay.tar.gz"), str(tmpdir) + "/"
    )
    cpio.assert_called_once_with(str(tmpdir), decompress_file())
    compress_file.assert_called_once_with(decompress_file(), "gz")

    assert caplog.record_tuples == [
        ("dispatcher", 20, f"Modifying '{tmpdir}/rootfs.cpio.gz'"),
        ("dispatcher", 10, "* decompressing (gz)"),
        ("dispatcher", 10, f"* extracting {decompress_file()}"),
        ("dispatcher", 10, "Overlays:"),
        (
            "dispatcher",
            10,
            f"- rootfs.lava: untar '{tmpdir}/overlay.tar.gz' to '{tmpdir}/'",
        ),
        ("dispatcher", 10, f"* archiving {decompress_file()}"),
        ("dispatcher", 10, "* compressing (gz)"),
    ]
Esempio n. 3
0
def test_append_overlays_update_guestfs(caplog, mocker, tmpdir):
    caplog.set_level(logging.DEBUG)
    params = {
        "format": "ext4",
        "overlays": {
            "modules": {
                "url": "http://example.com/modules.tar.xz",
                "compression": "xz",
                "format": "tar",
                "path": "/lib",
            }
        },
    }

    action = AppendOverlays("rootfs", params)
    action.job = Job(1234, {}, None)
    action.parameters = {
        "rootfs": {
            "url": "http://example.com/rootff.ext4",
            **params
        },
        "namespace": "common",
    }
    action.data = {
        "common": {
            "download-action": {
                "rootfs": {
                    "file": str(tmpdir / "rootfs.ext4"),
                    "compression": "gz",
                    "decompressed": True,
                },
                "rootfs.modules": {
                    "file": str(tmpdir / "modules.tar")
                },
            }
        }
    }

    guestfs = mocker.MagicMock()
    guestfs.add_drive = mocker.MagicMock()
    mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.guestfs.GuestFS",
        guestfs)
    action.update_guestfs()

    guestfs.assert_called_once_with(python_return_dict=True)
    guestfs().launch.assert_called_once_with()
    guestfs().list_devices.assert_called_once_with()
    guestfs().add_drive.assert_called_once_with(str(tmpdir / "rootfs.ext4"))
    guestfs().mount.assert_called_once_with(guestfs().list_devices()[0], "/")
    guestfs().mkdir_p.assert_called_once_with("/lib")
    guestfs().tar_in.assert_called_once_with(str(tmpdir / "modules.tar"),
                                             "/lib",
                                             compress=None)
    assert caplog.record_tuples == [
        ("dispatcher", 20, f"Modifying '{tmpdir}/rootfs.ext4'"),
        ("dispatcher", 10, "Overlays:"),
        ("dispatcher", 10,
         f"- rootfs.modules: '{tmpdir}/modules.tar' to '/lib'"),
    ]
Esempio n. 4
0
    def populate(self, parameters):
        self.pipeline = Pipeline(parent=self,
                                 job=self.job,
                                 parameters=parameters)

        # Find the right action according to the url
        url = self.params.get("url")
        if url is None:
            raise JobError("Invalid deploy action: 'url' is missing for '%s'" %
                           self.key)

        url = urlparse(url)
        if url.scheme == "scp":
            action = ScpDownloadAction(self.key,
                                       self.path,
                                       url,
                                       self.uniquify,
                                       params=self.params)
        elif url.scheme == "http" or url.scheme == "https":
            action = HttpDownloadAction(self.key,
                                        self.path,
                                        url,
                                        self.uniquify,
                                        params=self.params)
        elif url.scheme == "file":
            action = FileDownloadAction(self.key,
                                        self.path,
                                        url,
                                        self.uniquify,
                                        params=self.params)
        elif url.scheme == "lxc":
            action = LxcDownloadAction(self.key, self.path, url)
        elif url.scheme == "downloads":
            action = PreDownloadedAction(self.key,
                                         url,
                                         self.path,
                                         params=self.params)
        else:
            raise JobError("Unsupported url protocol scheme: %s" % url.scheme)
        self.pipeline.add_action(action)
        overlays = self.params.get("overlays", [])
        for overlay in overlays:
            if overlay == "lava":
                # Special case, don't download an overlay, just defined where to find overlays
                continue
            self.pipeline.add_action(
                DownloaderAction("%s.%s" % (self.key, overlay),
                                 self.path,
                                 params=overlays[overlay]))
        if overlays:
            self.pipeline.add_action(
                AppendOverlays(self.key, params=self.params))
Esempio n. 5
0
def test_append_overlays_validate():
    # 1/ Working setup
    params = {
        "format": "cpio.newc",
        "overlays": {
            "modules": {
                "url": "http://example.com/modules.tar.xz",
                "compression": "xz",
                "format": "tar",
                "path": "/",
            }
        },
    }
    action = AppendOverlays("rootfs", params)
    action.validate()

    # 2/ Check errors
    with pytest.raises(JobError) as exc:
        del params["format"]
        action.validate()
    assert exc.match("Unsupported image format None")

    with pytest.raises(JobError) as exc:
        params["overlays"]["modules"]["path"] = "../../"
        action.validate()
    assert exc.match("Invalid 'path': '../../'")

    with pytest.raises(JobError) as exc:
        del params["overlays"]["modules"]["path"]
        action.validate()
    assert exc.match("Missing 'path' for 'overlays.modules'")

    with pytest.raises(JobError) as exc:
        params["overlays"]["modules"]["format"] = "git"
        action.validate()
    assert exc.match("Invalid 'format' \\('git'\\) for 'overlays.modules'")

    with pytest.raises(JobError) as exc:
        params["overlays"] = ""
        action.validate()
    assert exc.match("'overlays' is not a dictionary")

    with pytest.raises(JobError) as exc:
        del params["overlays"]
        action.validate()
    assert exc.match("Missing 'overlays' dictionary")

    params = {
        "format": "cpio.newc",
        "overlays": {
            "modules": {
                "url": "http://example.com/modules.tar.xz",
                "compression": "xz",
                "format": "tar",
                "path": "/",
            }
        },
    }

    action = AppendOverlays("rootfs", params)
    action.validate()
    with pytest.raises(JobError) as exc:
        params["sparse"] = True
        action.validate()
    assert exc.match("sparse=True is only available for ext4 images")
Esempio n. 6
0
def test_append_lava_overlay_update_tar(caplog, mocker, tmpdir):
    caplog.set_level(logging.DEBUG)
    params = {
        "format": "tar",
        "overlays": {
            "modules": {
                "url": "http://example.com/modules.tar.xz",
                "compression": "xz",
                "format": "tar",
                "path": "/",
            }
        },
    }

    action = AppendOverlays("nfsrootfs", params)
    action.job = Job(1234, {}, None)
    action.parameters = {
        "nfsrootfs": {"url": "http://example.com/rootfs.tar.gz", **params},
        "namespace": "common",
    }
    action.data = {
        "common": {
            "download-action": {
                "nfsrootfs": {
                    "file": str(tmpdir / "rootfs.tar.gz"),
                    "compression": "gz",
                    "decompressed": False,
                },
                "nfsrootfs.modules": {"file": str(tmpdir / "modules.tar")},
            },
        }
    }
    action.mkdtemp = lambda: str(tmpdir)
    decompress_file = mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.decompress_file"
    )
    untar_file = mocker.patch("lava_dispatcher.actions.deploy.apply_overlay.untar_file")
    unlink = mocker.patch("os.unlink")
    create_tarfile = mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.create_tarfile"
    )
    compress_file = mocker.patch(
        "lava_dispatcher.actions.deploy.apply_overlay.compress_file"
    )

    action.update_tar()

    decompress_file.assert_called_once_with(str(tmpdir / "rootfs.tar.gz"), "gz")
    assert untar_file.mock_calls == [
        mocker.call(decompress_file(), str(tmpdir)),
        mocker.call(str(tmpdir / "modules.tar"), str(tmpdir) + "/"),
    ]
    unlink.assert_called_once_with(decompress_file())

    create_tarfile.assert_called_once_with(str(tmpdir), decompress_file())
    compress_file.assert_called_once_with(decompress_file(), "gz")

    assert caplog.record_tuples == [
        ("dispatcher", 20, f"Modifying '{tmpdir}/rootfs.tar.gz'"),
        ("dispatcher", 10, "* decompressing (gz)"),
        ("dispatcher", 10, f"* extracting {decompress_file()}"),
        ("dispatcher", 10, "Overlays:"),
        (
            "dispatcher",
            10,
            f"- nfsrootfs.modules: untar '{tmpdir}/modules.tar' to '{tmpdir}/'",
        ),
        ("dispatcher", 10, f"* archiving {decompress_file()}"),
        ("dispatcher", 10, "* compressing (gz)"),
    ]