Ejemplo n.º 1
0
def test_init_state_fail(gstate: GlobalState,
                         fs: fake_filesystem.FakeFilesystem) -> None:

    from gravel.controllers.nodes.mgr import NodeError

    if fs.exists("/etc/aquarium/node.json"):
        fs.remove("/etc/aquarium/node.json")

    nodemgr = NodeMgr(gstate)
    assert fs.exists("/etc/aquarium/node.json")
    for f in fs.listdir("/etc/aquarium"):
        fs.remove(f"/etc/aquarium/{f}")
    assert fs.exists("/etc/aquarium")
    fs.rmdir("/etc/aquarium")
    fs.create_dir("/etc/aquarium", perm_bits=0o500)

    throws = False
    try:
        nodemgr._init_state()
    except NodeError:
        throws = True
    assert throws

    # clean up
    for f in fs.listdir("/etc/aquarium"):
        fs.remove(f"/etc/aquarium/{f}")
    fs.rmdir("/etc/aquarium")
Ejemplo n.º 2
0
async def test_mount_error(
    gstate: GlobalState,
    fs: fake_filesystem.FakeFilesystem,
    mocker: MockerFixture,
) -> None:
    async def mock_call(
        cmd: List[str],
    ) -> Tuple[int, Optional[str], Optional[str]]:
        raise Exception("Failed mount.")

    mocker.patch(
        "gravel.controllers.nodes.systemdisk.aqr_run_cmd", new=mock_call
    )
    from gravel.controllers.nodes.systemdisk import MountError, SystemDisk

    systemdisk = SystemDisk(gstate)
    asserted = False
    try:
        await systemdisk.mount()
    except AssertionError:
        asserted = True
    assert asserted

    fs.create_file("/dev/mapper/aquarium-systemdisk")
    throws = False
    try:
        await systemdisk.mount()
    except MountError:
        throws = True
    assert throws
    assert fs.exists("/var/lib/aquarium-system")
Ejemplo n.º 3
0
def test_ctor(gstate: GlobalState, fs: fake_filesystem.FakeFilesystem) -> None:

    NodeMgr(gstate)
    assert fs.exists("/etc/aquarium/node.json")

    # clean up
    for f in fs.listdir("/etc/aquarium"):
        fs.remove(f"/etc/aquarium/{f}")
Ejemplo n.º 4
0
async def test_set_hostname(
    mocker: MockerFixture,
    fs: fake_filesystem.FakeFilesystem,
    get_data_contents: Callable[[str, str], str],
) -> None:

    called_set_hostname = False

    async def mock_call(
        cmd: List[str], ) -> Tuple[int, Optional[str], Optional[str]]:
        nonlocal called_set_hostname
        called_set_hostname = True
        assert cmd[0] == "hostnamectl"
        assert cmd[1] == "set-hostname"
        assert cmd[2] == "foobar"
        return 0, None, None

    async def mock_call_fail(
        cmd: List[str], ) -> Tuple[int, Optional[str], Optional[str]]:
        return 1, None, "oops"

    from gravel.controllers.nodes.host import HostnameCtlError, set_hostname

    mocker.patch("socket.gethostname", return_value="myhostname")

    mocker.patch("gravel.controllers.nodes.host.aqr_run_cmd",
                 new=mock_call_fail)
    throws = False
    try:
        await set_hostname("foobar")
    except HostnameCtlError as e:
        assert "oops" in e.message
        throws = True
    assert throws
    assert not fs.exists("/etc/hosts")

    mocker.patch("gravel.controllers.nodes.host.aqr_run_cmd", new=mock_call)
    fs.create_file("/etc/hosts")
    hosts = get_data_contents(DATA_DIR, "hosts.raw")
    with open("/etc/hosts", "w") as f:
        f.write(hosts)

    await set_hostname("foobar")
    assert called_set_hostname
    with open("/etc/hosts", "r") as f:
        text = f.read()
        assert text.count("myhostname") == 0
        assert text.count("foobar") == 2
Ejemplo n.º 5
0
def test_fail_ctor(gstate: GlobalState,
                   fs: fake_filesystem.FakeFilesystem) -> None:

    from gravel.controllers.nodes.mgr import NodeError

    if fs.exists("/etc/aquarium/node.json"):
        fs.remove("/etc/aquarium/node.json")
    fs.create_dir("/etc/aquarium/node.json")
    throws = False
    try:
        NodeMgr(gstate)
    except NodeError:
        throws = True
    except Exception:
        assert False
    assert throws
    # clean up
    fs.rmdir("/etc/aquarium/node.json")
Ejemplo n.º 6
0
async def test_enable(
    gstate: GlobalState,
    fs: fake_filesystem.FakeFilesystem,
    mocker: MockerFixture,
) -> None:

    from gravel.controllers.nodes.systemdisk import (
        MountError,
        OverlayError,
        SystemDisk,
    )

    async def mount_fail() -> None:
        raise MountError("Failed mount.")

    overlayed_paths = []
    bindmounts = []

    async def mock_call(
        cmd: List[str],
    ) -> Tuple[int, Optional[str], Optional[str]]:

        if cmd[2] == "overlay":
            assert "lower" in cmd[4]
            lowerstr = (cmd[4].split(","))[0]
            lower = (lowerstr.split("="))[1]
            overlayed_paths.append(lower)
        elif cmd[1] == "--bind":
            assert len(cmd) == 4
            bindmounts.append(cmd[3])
        else:
            raise Exception(f"Unknown call: {cmd}")
        return 0, None, None

    # ensure we don't have a mounted fs
    fs.add_real_file(
        source_path=os.path.join(DATA_DIR, "mounts_without_aquarium.raw"),
        target_path="/proc/mounts",
    )

    systemdisk = SystemDisk(gstate)
    assert not systemdisk.mounted
    systemdisk.mount = mount_fail

    mocker.patch(
        "gravel.controllers.nodes.systemdisk.aqr_run_cmd", new=mock_call
    )

    throws = False
    try:
        await systemdisk.enable()
    except OverlayError as e:
        assert "failed mount" in e.message.lower()
        throws = True
    assert throws

    systemdisk.mount = mocker.AsyncMock()

    for upper in systemdisk._overlaydirs.keys():
        fs.create_dir(f"/var/lib/aquarium-system/{upper}/overlay")
        fs.create_dir(f"/var/lib/aquarium-system/{upper}/temp")

    for ours in systemdisk._bindmounts.keys():
        fs.create_dir(f"/var/lib/aquarium-system/{ours}")

    await systemdisk.enable()

    for lower in systemdisk._overlaydirs.values():
        assert fs.exists(lower)
        assert lower in overlayed_paths

    for theirs in systemdisk._bindmounts.values():
        assert fs.exists(theirs)
        assert theirs in bindmounts
Ejemplo n.º 7
0
async def test_init(fs: fake_filesystem.FakeFilesystem) -> None:

    from gravel.controllers.deployment.mgr import (
        AlreadyInitedError,
        DeploymentMgr,
        InitError,
        InitStateEnum,
        NotPreInitedError,
    )

    mgr = DeploymentMgr()

    raised: bool = False
    try:
        await mgr.init()
    except NotPreInitedError:
        raised = True
    except Exception:
        assert False
    assert raised

    mgr._preinited = True
    mgr._inited = True
    raised = False
    try:
        await mgr.init()
    except AlreadyInitedError:
        raised = True
    except Exception:
        assert False
    assert raised

    mgr._preinited = True
    mgr._inited = False
    await mgr.init()  # succeeds because we're not installed yet.
    assert mgr._init_state < InitStateEnum.INSTALLED

    # test canonical case, we're installed but don't have a state yet.
    fs.reset()
    mgr = DeploymentMgr()
    mgr._preinited = True
    mgr._inited = False
    mgr._init_state = InitStateEnum.INSTALLED

    assert not fs.exists("/etc/aquarium")
    await mgr.init()
    assert mgr._inited
    assert fs.exists("/etc/aquarium/")
    assert fs.isdir("/etc/aquarium")
    assert fs.exists("/etc/aquarium/state.json")

    # ensure we have a malformed file in /etc/aquarium/state.json
    fs.reset()
    mgr = DeploymentMgr()
    mgr._preinited = True
    mgr._inited = False
    mgr._init_state = InitStateEnum.INSTALLED

    fs.create_dir("/etc/aquarium")
    with open("/etc/aquarium/state.json", "w") as f:
        f.write("foobarbaz")

    raised = False
    try:
        await mgr.init()
    except InitError:
        raised = True
    except Exception:
        assert False
    assert raised

    # now we have something in state.json that is not a file
    fs.reset()
    mgr = DeploymentMgr()
    mgr._preinited = True
    mgr._inited = False
    mgr._init_state = InitStateEnum.INSTALLED

    fs.create_dir("/etc/aquarium/state.json")
    raised = False
    try:
        await mgr.init()
    except InitError:
        raised = True
    except Exception:
        assert False
    assert raised