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
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
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
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
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
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
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