2014-03-23 23:12:07 +01:00
|
|
|
from bootstrapvz.base import Task
|
|
|
|
from .. import phases
|
|
|
|
from ..exceptions import TaskError
|
2013-07-10 10:49:45 +02:00
|
|
|
|
|
|
|
|
2014-02-23 21:51:28 +01:00
|
|
|
class CheckExternalCommands(Task):
|
2016-06-04 11:35:59 +02:00
|
|
|
description = 'Checking availability of external commands'
|
2016-09-12 00:52:10 +02:00
|
|
|
phase = phases.validation
|
2013-07-10 10:49:45 +02:00
|
|
|
|
2016-06-04 11:35:59 +02:00
|
|
|
@classmethod
|
|
|
|
def run(cls, info):
|
|
|
|
import re
|
2017-07-02 17:16:25 +02:00
|
|
|
import os
|
Fix unfailing CheckExternalCommands
On Unix, with shell=True, the shell default to /bin/sh.
Using Popen(['type', command], shell=True) is equivalent to calling
Popen(['/bin/sh', '-c', 'type', command]).
In this case 'command' becomes a positional parameter to the shell,
and not an argument to the command 'type'.
The solution is to pass a single string as parameter.
The problem is that with shell=True, we are never safe from a shell injection,
so it is wiser to use a python only solution.
The package distutils is part of the standard distribution, so it doesn't add
extra dependencies.
The method find_executable has the same behaviour as 'which' on bash.
2017-05-26 04:20:56 +02:00
|
|
|
import logging
|
2018-02-18 20:22:05 -08:00
|
|
|
# https://github.com/PyCQA/pylint/issues/73
|
|
|
|
# pylint: disable=no-name-in-module,import-error,useless-suppression
|
Fix unfailing CheckExternalCommands
On Unix, with shell=True, the shell default to /bin/sh.
Using Popen(['type', command], shell=True) is equivalent to calling
Popen(['/bin/sh', '-c', 'type', command]).
In this case 'command' becomes a positional parameter to the shell,
and not an argument to the command 'type'.
The solution is to pass a single string as parameter.
The problem is that with shell=True, we are never safe from a shell injection,
so it is wiser to use a python only solution.
The package distutils is part of the standard distribution, so it doesn't add
extra dependencies.
The method find_executable has the same behaviour as 'which' on bash.
2017-05-26 04:20:56 +02:00
|
|
|
from distutils.spawn import find_executable
|
2016-06-04 11:35:59 +02:00
|
|
|
missing_packages = []
|
Fix unfailing CheckExternalCommands
On Unix, with shell=True, the shell default to /bin/sh.
Using Popen(['type', command], shell=True) is equivalent to calling
Popen(['/bin/sh', '-c', 'type', command]).
In this case 'command' becomes a positional parameter to the shell,
and not an argument to the command 'type'.
The solution is to pass a single string as parameter.
The problem is that with shell=True, we are never safe from a shell injection,
so it is wiser to use a python only solution.
The package distutils is part of the standard distribution, so it doesn't add
extra dependencies.
The method find_executable has the same behaviour as 'which' on bash.
2017-05-26 04:20:56 +02:00
|
|
|
log = logging.getLogger(__name__)
|
2016-06-04 11:35:59 +02:00
|
|
|
for command, package in info.host_dependencies.items():
|
Fix unfailing CheckExternalCommands
On Unix, with shell=True, the shell default to /bin/sh.
Using Popen(['type', command], shell=True) is equivalent to calling
Popen(['/bin/sh', '-c', 'type', command]).
In this case 'command' becomes a positional parameter to the shell,
and not an argument to the command 'type'.
The solution is to pass a single string as parameter.
The problem is that with shell=True, we are never safe from a shell injection,
so it is wiser to use a python only solution.
The package distutils is part of the standard distribution, so it doesn't add
extra dependencies.
The method find_executable has the same behaviour as 'which' on bash.
2017-05-26 04:20:56 +02:00
|
|
|
log.debug('Checking availability of ' + command)
|
2017-07-02 17:16:25 +02:00
|
|
|
path = find_executable(command)
|
|
|
|
if path is None or not os.access(path, os.X_OK):
|
2019-03-05 19:01:05 +00:00
|
|
|
if re.match(r'^https?:\/\/', package):
|
2016-06-04 11:35:59 +02:00
|
|
|
msg = ('The command `{command}\' is not available, '
|
|
|
|
'you can download the software at `{package}\'.'
|
|
|
|
.format(command=command, package=package))
|
|
|
|
else:
|
|
|
|
msg = ('The command `{command}\' is not available, '
|
|
|
|
'it is located in the package `{package}\'.'
|
|
|
|
.format(command=command, package=package))
|
|
|
|
missing_packages.append(msg)
|
2018-02-18 20:41:40 -08:00
|
|
|
if missing_packages:
|
2016-06-04 11:35:59 +02:00
|
|
|
msg = '\n'.join(missing_packages)
|
|
|
|
raise TaskError(msg)
|