Server : Apache System : Linux server1.cgrithy.com 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Jul 24 13:59:37 UTC 2023 x86_64 User : nobody ( 99) PHP Version : 8.1.23 Disable Function : NONE Directory : /usr/local/bin/ |
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - ea-passenger-runtime-applications-settings # Copyright 2021 cPanel, L.L.C. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited package scripts::ea_passenger_settings; use strict; use warnings; use Cpanel::JSON (); use Path::Tiny (); use Cpanel::Config::userdata::PassengerApps (); use Cpanel::ConfigFiles::Apache 'apache_paths_facade'; # see POD for import specifics run(@ARGV) if !caller; sub run { my (@args) = @_; my $fix = grep( m/^--fix/, @args ) ? 1 : 0; if ( $fix && @args > 1 || !$fix && @args > 0 ) { die "Invalid arguments. Either pass no args (to report problems) or pass only --fix (to fix problems).\n"; } _verify_defaults_and_settings($fix); my %settings = ( ruby => scalar( _load_setting("ruby") ), python => scalar( _load_setting("python") ), nodejs => scalar( _load_setting("nodejs") ), ); my %needs_fixed; USER: for my $userapps ( glob('/var/cpanel/userdata/*/applications.json') ) { my $apps = Cpanel::JSON::LoadFile($userapps); my $user = $userapps; $user =~ s{^/var/cpanel/userdata/}{}; $user =~ s{/applications\.json$}{}; APP: for my $appname ( sort keys %{$apps} ) { my $app = $apps->{$appname}; TYPE: for my $type ( keys %settings ) { my $path = $app->{$type}; if ( !length($path) || !-x $path ) { if ( length( $settings{$type} ) && !-x $settings{$type} ) { warn "$user’s app “$appname” has an invalid “$type” setting but can’t be reset because the global “$type” seeting is invalid also. If this app uses “$type” it will not work until “$type” is installed!\n"; next TYPE; } $needs_fixed{$user}{$appname}{$type}{old} = $path; $needs_fixed{$user}{$appname}{$type}{new} = $settings{$type}; } } } } if ( !keys %needs_fixed ) { print "No passenger application settings need fixed.\n"; return; } if ($fix) { print "Fixing passenger application settings …\n"; _perform_fixes( \%needs_fixed ); } else { print "Passenger application setting problems (pass --fix to fix problems):\n"; print Cpanel::JSON::pretty_canonical_dump( \%needs_fixed ); } return; } ############### #### helpers ## ############### sub _load_setting { my ($type) = @_; my $value = Path::Tiny::path("/etc/cpanel/ea4/passenger.$type")->slurp; chomp $value; # juuuust in case warn "“$type” setting “$value” is not executable!\n" if !-x $value; return $value; } sub _perform_fixes { my ($needs_fixed_hr) = @_; if ( !-x apache_paths_facade->bin_httpd() ) { warn "Apache binary is missing (not yet installed?) so we can’t fix the passenger config. Please re-run `$0 --fix` after Apache is installed.\n"; return; } for my $user ( sort keys %{$needs_fixed_hr} ) { print "\t … user “$user” …\n"; my $file = "/var/cpanel/userdata/$user/applications.json"; my $apps = Cpanel::JSON::LoadFile($file); for my $appname ( sort keys %{ $needs_fixed_hr->{$user} } ) { print "\t\t … application “$appname” …\n"; for my $type ( sort keys %{ $needs_fixed_hr->{$user}{$appname} } ) { my $new = $needs_fixed_hr->{$user}{$appname}{$type}{new}; my $old = $needs_fixed_hr->{$user}{$appname}{$type}{old} // ""; print "\t\t\t … type “$type”: changing from “$old” to “$new”.\n"; $apps->{$appname}{$type} = $new; } } # save settings Cpanel::JSON::DumpFile( $file, $apps ); # regen service confs my $obj = Cpanel::Config::userdata::PassengerApps->new( { user => $user } ); my $appz = $obj->list_applications(); for my $name ( keys %{$appz} ) { if ( $appz->{$name}{enabled} ) { $obj->generate_apache_conf($name); } } if ( -x "/usr/local/cpanel/scripts/ea-nginx" ) { system( '/usr/local/cpanel/scripts/ea-nginx', 'config', $user, '--no-reload' ); } } # restart services system("/usr/local/cpanel/scripts/restartsrv_httpd --restart"); if ( -x "/usr/local/cpanel/scripts/ea-nginx" ) { system("/usr/local/cpanel/scripts/ea-nginx reload"); } return; } sub _verify_defaults_and_settings { my ($fix) = @_; my $default_ruby = `find /usr/bin -name 'ruby*' -executable | sort -r | head -n 1`; my $default_python = `find /usr/bin -name 'python*' -executable ! -name "*-config" ! -name "pythonw*" | sort -r | head -n 1`; my $default_nodejs = `find /usr/bin -name 'node*' -executable | sort -r | head -n 1`; chomp $default_ruby; chomp $default_python; chomp $default_nodejs; # 1. Verify defaults exist on system _verify_default( ruby => $default_ruby, $fix ); _verify_default( python => $default_python, $fix ); _verify_default( nodejs => $default_nodejs, $fix ); print "\n"; # 2. Verify settings exist on system _verify_passenger_setting( ruby => $default_ruby, $fix ); _verify_passenger_setting( python => $default_python, $fix ); _verify_passenger_setting( nodejs => $default_nodejs, $fix ); print "\n"; return; } sub _verify_default { my ( $name, $have, $fix ) = @_; my $path = "/etc/cpanel/ea4/passenger.$name.system-default"; # if default does not even exist this will create it ($target will be empty) my $target = readlink($path) || ""; my $is_fallback = $target eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ? 1 : 0; if ( !-x $target || $is_fallback ) { if ($is_fallback) { print "Default is fallback helper, attempting to re-set it\n"; } else { print "Default $name, $target, is not executable\n"; } if ( !$have ) { print "\t … no $name found on system, "; if ($fix) { print "leaving currently invalid value in place\n"; } else { print "currently invalid value would remain in place\n"; } } else { if ($fix) { print "\t … updating to “$have”\n"; unlink $path; symlink $have, $path; } else { print "\t … would update to “$have” (pass --fix to fix this problem)\n"; } } } else { print "Default $name, $target, is ok\n"; } return; } sub _verify_passenger_setting { my ( $name, $have, $fix ) = @_; print "Verifying passenger setting for $name\n"; my $path = "/etc/cpanel/ea4/passenger.$name"; if ( -s $path ) { my $curr = Path::Tiny::path($path)->slurp; chomp $curr; # juuuust in case my $is_fallback = $curr eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ? 1 : 0; if ( !-x $curr || $is_fallback ) { if ($is_fallback) { print "\t$name’s setting is fallback helper\n"; } else { print "\t$name’s setting, $curr, is not executable\n"; } if ($have) { _reset_passenger_setting( $name => $have, $fix ); } else { _set_to_default( $name, $fix ); } } else { print "\t$name setting, $curr, is ok\n"; } } else { print "\t$name is not configured for passenger, using default.\n"; _set_to_default( $name, $fix ); } return; } sub _set_to_default { my ( $name, $fix ) = @_; my $defaultpath = readlink("/etc/cpanel/ea4/passenger.$name.system-default") || ""; my $defdisp = $defaultpath; my $isplaceholder = 0; if ( $defdisp eq "/usr/local/bin/ea-passenger-runtime_$name-is-not-installed" ) { $isplaceholder = 1; $defdisp = $name; } if ($isplaceholder) { print "The default is invalid. Passenger apps using it will not work until $defdisp is installed!\n"; print "Passenger itself will not work until until $defdisp is installed!\n" if $name eq "ruby"; } elsif ( !-x $defaultpath ) { print "The default, $defaultpath, is not executable. Passenger apps using it will not work until $defdisp is installed!\n"; print "Passenger itself will not work until until $defdisp is installed!\n" if $name eq "ruby"; } _reset_passenger_setting( $name => $defaultpath, $fix ); return; } sub _reset_passenger_setting { my ( $name, $value, $fix ) = @_; if ($fix) { print "\t\tResetting $name setting to $value\n"; Path::Tiny::path("/etc/cpanel/ea4/passenger.$name")->spew($value); } else { print "\t\t“$name” needs reset to “$value” (pass --fix to fix this problem)\n"; } return; } 1;