Mini Shell
#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - SOURCES/ea-nginx-rpmtool Copyright 2019 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
use strict;
use warnings;
use Path::Tiny;
use JSON::Syck ();
use Cpanel::SafeRun::Object ();
use Cpanel::ServerTasks ();
use Cpanel::Transaction::File::JSON ();
my $meta_dir = "/etc/nginx/ea-nginx/meta";
my $settings = "/etc/nginx/ea-nginx/settings.json";
my %default = ( apache_port => 80, apache_ssl_port => 443 );
my $task = $ARGV[0];
if ( !defined $task || ( $task ne "move_apache_to_alt_ports" && $task ne "move_apache_back_to_orig_ports" ) ) {
die "Invalid task\n"; # no help because this should never be run outside of the RPM
}
else {
print "Running $task() …\n";
no strict "refs";
$task->();
}
#############
#### tasks ##
#############
sub move_apache_to_alt_ports {
for my $key (qw(apache_port apache_ssl_port)) {
if ( !-s "$meta_dir/$key.initial" ) {
my $cur_ts_val = _get_ts($key) || "0.0.0.0:$default{$key}";
my ( $ip_part, $port_part ) = split( /:/, $cur_ts_val, 2 );
if ( !$port_part ) {
$port_part = $ip_part;
$ip_part = "0.0.0.0";
}
path("$meta_dir/$key.initial")->spew($cur_ts_val);
my $new_port;
if ( $default{$key} eq $port_part ) {
$new_port = _get_new_port($port_part);
_set_ts( $key, "$ip_part:$new_port" );
}
else {
$new_port = $port_part;
}
my $cur_settings = _get_settings();
$ip_part = "127.0.0.1" if !$ip_part || $ip_part eq '0.0.0.0';
$cur_settings->{$key} = $new_port;
$cur_settings->{ $key . "_ip" } = $ip_part;
_set_settings($cur_settings);
}
}
if ( !-s "/etc/nginx/conf.d/ea-nginx.conf" ) {
# not complicated enough to justify pulling in Template::Toolkit
my $cur_settings = _get_settings();
my $cont = path("/etc/nginx/ea-nginx/ea-nginx.conf.tt")->slurp;
for my $key (qw(apache_port apache_ssl_port apache_port_ip server_names_hash_max_size server_names_hash_bucket_size)) {
$cont =~ s/\[% settings\.$key %\]/$cur_settings->{$key}/g;
}
path("/etc/nginx/conf.d/ea-nginx.conf")->spew($cont);
}
# EA-10977 - Since we now calculate these values each time the config script executes,
# we need to remove them from settings.json in order to avoid end user
# confusion regarding them
for my $key (qw(server_names_hash_max_size server_names_hash_bucket_size)) {
my $cur_settings = _get_settings();
delete $cur_settings->{$key};
_set_settings($cur_settings);
}
}
sub move_apache_back_to_orig_ports {
for my $key (qw(apache_port apache_ssl_port)) {
if ( -s "$meta_dir/$key.initial" ) {
# ¿TODO/YAGNI? - warn if _get_ts($key) ip/port does not
# match what is in /etc/nginx/ea-nginx/settings.json
# noop if apache was already not on non-standard ports
my $pre_nginx_val = path("/etc/nginx/ea-nginx/meta/$key.initial")->slurp;
_set_ts( $key, $pre_nginx_val );
path("$meta_dir/$key.initial")->spew("");
my $cur_settings = _get_settings();
$cur_settings->{$key} = undef;
$cur_settings->{ $key . "_ip" } = undef;
_set_settings($cur_settings);
}
}
Cpanel::ServerTasks::schedule_task( ['ApacheTasks'], 5, 'userdata_update' );
}
###############
#### helpers ##
###############
sub _get_ts {
my ($key) = @_;
return _get_apicall( 'get_tweaksetting', "key=$key" );
}
sub _set_ts {
my ( $key, $val ) = @_;
return _get_apicall( 'set_tweaksetting', "key=$key", "value=$val" );
}
sub _get_apicall {
my ( $function, @args ) = @_;
my $run = Cpanel::SafeRun::Object->new( program => '/usr/local/cpanel/bin/whmapi1', args => [ $function, '--output=json', @args ] );
if ( $run->CHILD_ERROR() ) {
warn $run->CHILD_ERROR() . "\n";
return;
}
else {
my $hr = eval { JSON::Syck::Load( $run->stdout() ) };
if ( !$hr || !$hr->{metadata}{result} ) {
warn "whmapi1 $function failed: $hr->{metadata}{reason}\n";
return;
}
return $hr->{data}{tweaksetting}{value};
}
}
sub _get_settings {
my $hr = eval { JSON::Syck::LoadFile($settings) };
if ( $@ || !$hr ) {
warn "Could not load $settings: $@\n";
return;
}
return $hr;
}
sub _set_settings {
my ($hr) = @_;
my $transaction = Cpanel::Transaction::File::JSON->new( path => $settings, "permissions" => 0644 );
$transaction->set_data($hr);
eval {
$transaction->save_pretty_canonical_or_die();
$transaction->close_or_die();
};
if ($@) {
warn "Could not save $settings: $@\n";
return;
}
return 1;
}
sub _get_new_port {
my ($cur_port) = @_;
my $new_port;
$cur_port = 80 if $cur_port > 1022; # should never happen but just in case ¯\_(ツ)_/¯
for my $try_port ( $cur_port + 1 .. 1023 ) {
if ( !`netstat -tulpn | grep -e ':$try_port\b'` ) {
$new_port = $try_port;
last;
}
}
if ( !$new_port ) {
$new_port = $cur_port + 10;
warn "Could not determine an empty port, falling back to $new_port\n";
}
return $new_port;
}
Zerion Mini Shell 1.0