Example #1
0
def _check_docker_supports_mounts() -> CheckLevels:
    """
    This is to avoid:

    docker.errors.InvalidVersion: mounts param is not supported in API versions
    < 1.30
    """
    client = docker_client()
    mount = docker.types.Mount(source=None, target='/etc')
    # Any image will do, we use this for another test so using it here saves
    # pulling another image.
    tiny_image = 'luca3m/sleep'

    try:
        container = client.containers.run(
            image=tiny_image,
            mounts=[mount],
            detach=True,
        )
    except docker.errors.InvalidVersion as exc:
        if 'mounts param is not supported' in str(exc):
            message = (
                'The Docker API version must be >= 1.30. '
                'This is because DC/OS E2E uses the ``mounts`` parameter.')
            error(message=message)
            return CheckLevels.ERROR
        raise

    container.stop()
    container.remove(v=True)

    return CheckLevels.NONE
Example #2
0
def _check_storage_driver() -> CheckLevels:
    """
    Warn if the Docker storage driver is not a recommended driver.
    """
    client = docker_client()
    host_driver = client.info()['Driver']
    storage_driver_url = (
        'https://docs.docker.com/storage/storagedriver/select-storage-driver/')
    # Any image will do, we use this for another test so using it here saves
    # pulling another image.
    tiny_image = 'luca3m/sleep'
    container = client.containers.run(
        image=tiny_image,
        tty=True,
        detach=True,
        privileged=True,
        volumes={'/proc': {
            'bind': '/host/proc',
            'mode': 'rw',
        }},
    )

    cmd = ['cat', '/host/proc/filesystems']
    _, output = container.exec_run(cmd=cmd)
    container.stop()
    container.remove(v=True)
    aufs_supported = bool(b'aufs' in output.split())
    supported_host_driver = bool(host_driver in DOCKER_STORAGE_DRIVERS)
    can_work = bool(aufs_supported or supported_host_driver)

    if not can_work:
        message = (
            "The host's Docker storage driver is \"{host_driver}\". "
            'aufs is not available. '
            'Change your storage driver to one of: {supported_drivers}. '
            'Alternatively try using the `--docker-storage-driver` option '
            'with `overlay` or `overlay2`. '
            'See {help_url}.').format(
                host_driver=host_driver,
                supported_drivers=', '.join(
                    sorted(DOCKER_STORAGE_DRIVERS.keys())),
                help_url=storage_driver_url,
            )
        error(message=message)
        return CheckLevels.ERROR

    if not supported_host_driver:
        message = ("The host's Docker storage driver is \"{host_driver}\". "
                   'We recommend that you use one of: {supported_drivers}. '
                   'See {help_url}.').format(
                       host_driver=host_driver,
                       supported_drivers=', '.join(
                           sorted(DOCKER_STORAGE_DRIVERS.keys())),
                       help_url=storage_driver_url,
                   )
        warn(message=message)
        return CheckLevels.WARNING

    return CheckLevels.NONE
Example #3
0
def check_vagrant() -> CheckLevels:
    """
    Error if `vagrant` is not available on the path.
    """
    if shutil.which('vagrant') is None:
        error(message='`vagrant` must be available on the PATH.')
        return CheckLevels.ERROR
    return CheckLevels.NONE
Example #4
0
def _check_selinux() -> CheckLevels:
    """
    Error if SELinux is enabled.
    This can cause problems such as mount problems for the installer.
    """
    if shutil.which('getenforce') is None:
        return CheckLevels.NONE

    result = subprocess.check_output(args=['getenforce'])
    if result == b'Enforcing':
        message = ('SELinux is in "Enforcing" mode. '
                   'SELinux must be in "Permissive" or "Disabled" mode.')
        error(message=message)
        return CheckLevels.ERROR

    return CheckLevels.NONE
Example #5
0
def check_vagrant_plugins() -> CheckLevels:
    """
    Error if `vagrant-vbguest` is not installed.
    """
    # We import Vagrant here instead of at the top of the file because, if
    # the Vagrant executable is not found, a warning is logged.
    #
    # We want to avoid that warning for users of other backends who do not
    # have the Vagrant executable.
    import vagrant

    client = vagrant.Vagrant()
    if 'vagrant-vbguest' in set(plugin.name
                                for plugin in client.plugin_list()):
        return CheckLevels.NONE

    error(message='The `vagrant-vbguest` plugin must be installed.')
    return CheckLevels.ERROR
Example #6
0
def _check_mount_tmp() -> CheckLevels:
    """
    Error if it is not possible to mount the temporary directory.
    """
    highest_level = CheckLevels.NONE
    # Any image will do, we use this for another test so using it here saves
    # pulling another image.
    tiny_image = 'luca3m/sleep'
    client = docker_client()

    tmp_path = Path('/tmp').resolve()

    try:
        private_mount_container = client.containers.run(
            image=tiny_image,
            tty=True,
            detach=True,
            volumes={
                str(tmp_path): {
                    'bind': '/test',
                },
            },
        )
    except docker.errors.APIError as exc:
        message = (
            'There was an error mounting the temporary directory path '
            '"{tmp_path}" in container: \n\n'
            '{exception_detail}'
        ).format(
            tmp_path=tmp_path,
            exception_detail=exc.explanation.decode(
                'ascii',
                'backslashreplace',
            ),
        )
        error(message=message)
        highest_level = CheckLevels.ERROR

    private_mount_container.stop()
    private_mount_container.remove(v=True)
    return highest_level
Example #7
0
def _check_can_build() -> CheckLevels:
    """
    Check that the default cluster images can be built.
    """
    cluster_backend = Docker(docker_version=DockerVersion.v1_13_1)
    try:
        with Cluster(cluster_backend=cluster_backend):
            pass
    except docker.errors.BuildError as exc:
        message = (
            'There was an error building a Docker image. '
            'The Docker logs follow.\n'
            '\n'
        )
        for item in exc.build_log:
            if 'stream' in item:
                message += '\t' + item['stream']
        error(message=message)
        return CheckLevels.ERROR

    return CheckLevels.NONE