2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 18:59:33 +00:00

98_Installer: always run cpanm via sudo to circumvent wrong fhem $HOME dir

git-svn-id: https://svn.fhem.de/fhem/trunk@19218 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
jpawlowski 2019-04-18 17:48:36 +00:00
parent 476c7cbbdb
commit 9e62fdf590
2 changed files with 99 additions and 52 deletions

View File

@ -856,7 +856,10 @@ sub ExecuteFhemCommand($) {
$installer->{debug} = $cmd->{debug};
my $sudo = 'sudo -n ';
$installer->{cpanversions} = 'echo n | ' . 'cpanm --version 2>&1';
$installer->{cpanversions} =
'echo n | TEST=$(which cpanm) || echo "sh: command not found: cpanm"; which cpanm >/dev/null 2>&1 && sh -c "'
. $sudo
. '$(which cpanm) --version 2>&1" 2>&1';
$installer->{installperl} =
'echo n | sh -c "'
. $sudo
@ -884,11 +887,9 @@ sub ExecuteFhemCommand($) {
{
if ( $1 =~ /App::cpanminus/i ) {
$installer->{installperl} =
'echo n | if [ -z "$(cpanm --version 2>/dev/null)" ]; then'
. ' sh -c "curl -fsSL https://git.io/cpanm | '
'sh -c "curl -fsSL https://git.io/cpanm | '
. $sudo
. '$(which perl) - App::cpanminus >/dev/null 2>&1" 2>&1; '
. 'fi; '
. 'cpanm --version >/dev/null'
. ' && sh -c "'
. $sudo
@ -1001,6 +1002,8 @@ sub GetCpanVersion($) {
if ( $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?not.found$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?\w+?: [^:]*?not.found: (\S+)$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
)
{
@ -1008,6 +1011,30 @@ m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
$error->{summary} = "Not Found - $3 is not installed";
$error->{detail} = $line;
}
elsif ( $line =~ m/^sudo: /i ) {
my $error = {};
my $runningUser = getpwuid($<);
my $cpanmbin = `which cpanm`;
my $perlbin = `which perl`;
$cpanmbin =~ s/\n//g;
$perlbin =~ s/\n//g;
$error->{code} = "E403";
$error->{summary} =
"Forbidden - " . "passwordless sudo permissions required";
$error->{detail} =
$line
. "<br /><br />"
. "You may add the following lines to /etc/sudoers.d/$runningUser:\n"
. "<pre>"
. " $runningUser ALL=(ALL) NOPASSWD:SETENV: "
. $cpanmbin . " *"
. "\n $runningUser ALL=(ALL) NOPASSWD:SETENV: "
. $perlbin
. ' - App\:\:cpanminus'
. "</pre>";
push @{ $h->{error} }, $error;
last;
}
else {
$error->{code} = "E501";
$error->{summary} = "Parsing error";
@ -1088,6 +1115,8 @@ sub CpanInstall($) {
elsif ( $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?not.found$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?\w+?: [^:]*?not.found: (\S+)$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
)
{
@ -1103,7 +1132,9 @@ m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
my $error = {};
my $runningUser = getpwuid($<);
my $cpanmbin = `which cpanm`;
my $perlbin = `which perl`;
$cpanmbin =~ s/\n//g;
$perlbin =~ s/\n//g;
$error->{code} = "E403";
$error->{summary} =
"Forbidden - " . "passwordless sudo permissions required";
@ -1113,7 +1144,7 @@ m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
. "You may add the following lines to /etc/sudoers.d/$runningUser:\n"
. "<pre>"
. " $runningUser ALL=(ALL) NOPASSWD:SETENV: "
. $cpanmbin
. $perlbin
. ' - App\:\:cpanminus'
. "</pre>";
push @{ $h->{error} }, $error;
@ -1194,6 +1225,8 @@ sub CpanUninstall($) {
elsif ( $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?not.found$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?\w+?: [^:]*?not.found: (\S+)$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
)
{
@ -1329,6 +1362,8 @@ sub CpanOutdated($) {
if ( $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?not.found$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?\w+?: [^:]*?not.found: (\S+)$/i
or $line =~
m/(?:(\w+?): )?(?:(\w+? \d+): )?(\w+?): [^:]*?No.such.file.or.directory$/i
)
{

View File

@ -971,6 +971,8 @@ sub __PutMetadata {
return undef;
}
my $scanner; # keep the scanner defined
# Extract metadata from FHEM module file
sub __GetMetadata {
return 0 unless ( __PACKAGE__ eq caller(0) );
@ -1247,75 +1249,80 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
if ( keys %json > 0 ) {
# try to use JSON::MaybeXS wrapper
# for chance of better performance + open code
# See: https://perlmaven.com/comparing-the-speed-of-json-decoders
eval {
require JSON::MaybeXS;
import JSON::MaybeXS qw( decode_json );
1;
};
if ($@) {
$@ = undef;
unless ( defined( &{'decode_json'} ) ) {
# try to use JSON wrapper
# for chance of better performance
# try to use JSON::MaybeXS wrapper
# for chance of better performance + open code
# See: https://perlmaven.com/comparing-the-speed-of-json-decoders
eval {
require JSON;
import JSON qw( decode_json );
require JSON::MaybeXS;
import JSON::MaybeXS qw( decode_json );
1;
};
if ($@) {
$@ = undef;
# In rare cases, Cpanel::JSON::XS may
# be installed but JSON|JSON::MaybeXS not ...
# try to use JSON wrapper
# for chance of better performance
eval {
require Cpanel::JSON::XS;
import Cpanel::JSON::XS qw(decode_json encode_json);
require JSON;
import JSON qw( decode_json );
1;
};
if ($@) {
$@ = undef;
# In rare cases, JSON::XS may
# be installed but JSON not ...
# In rare cases, Cpanel::JSON::XS may
# be installed but JSON|JSON::MaybeXS not ...
eval {
require JSON::XS;
import JSON::XS qw(decode_json encode_json);
require Cpanel::JSON::XS;
import Cpanel::JSON::XS qw(decode_json encode_json);
1;
};
if ($@) {
$@ = undef;
# Fallback to built-in JSON which SHOULD
# be available since 5.014 ...
# In rare cases, JSON::XS may
# be installed but JSON not ...
eval {
require JSON::PP;
import JSON::PP qw(decode_json encode_json);
require JSON::XS;
import JSON::XS qw(decode_json encode_json);
1;
};
if ($@) {
$@ = undef;
# Fallback to JSON::backportPP in really rare cases
# Fallback to built-in JSON which SHOULD
# be available since 5.014 ...
eval {
require JSON::backportPP;
import JSON::backportPP
qw(decode_json encode_json);
require JSON::PP;
import JSON::PP qw(decode_json encode_json);
1;
};
if ($@) {
$@ = undef;
# Fallback to JSON::backportPP
# in really rare cases
eval {
require JSON::backportPP;
import JSON::backportPP
qw(decode_json encode_json);
1;
};
$@ = undef;
}
}
}
}
}
}
if ( !$@ ) {
if ( defined( &{'decode_json'} ) ) {
foreach ( keys %json ) {
next
if (
@ -1360,9 +1367,6 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
}
return undef if ($metaSection);
}
else {
$@ = undef;
}
}
# special place for fhem.pl is this module file
@ -1378,16 +1382,27 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
# Detect prereqs if not provided via META.json
if ( !defined( $modMeta->{prereqs} ) ) {
eval {
require Perl::PrereqScanner::NotQuiteLite;
1;
};
if ( !$@ ) {
my $scanner = Perl::PrereqScanner::NotQuiteLite->new(
parsers => [qw/:installed -UniversalVersion/],
suggests => 1,
);
# Initialize scanner first
unless ( defined($scanner) ) {
eval {
require Perl::PrereqScanner::NotQuiteLite;
1;
};
if ($@) {
$@ = undef;
}
else {
$scanner = Perl::PrereqScanner::NotQuiteLite->new(
parsers => [qw/:installed -UniversalVersion/],
suggests => 1,
);
}
}
# Scan files
if ( defined($scanner) ) {
my $context = $scanner->scan_file($filePath);
my $requirements = $context->requires;
my $recommends = $context->recommends;
@ -1446,9 +1461,6 @@ m/(^#\s+(?:\d{1,2}\.\d{1,2}\.(?:\d{2}|\d{4})\s+)?[^v\d]*(v?(?:\d{1,3}\.\d{1,3}(?
}
}
}
else {
$@ = undef;
}
}
else {
$modMeta->{x_prereqs_src} = 'META.json';