blob: 19924ba4e0acf78c9353db973d1a4d100a2a4890 [file] [log] [blame]
#!/inktest/dist/bin/perl
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# ts-instantiate.pl
#
#
# Description:
# script to manage traffic_server under the DEFT testing
# framework
#
#
#
#
use strict vars;
use English;
use File::Copy;
our $bin_dir;
our $run_dir;
our $base_port = 0;
our @additional_config_entries = ("CONFIG proxy.config.raf.enabled INT 1",
"CONFIG proxy.config.raf.port INT <alloc_port>");
our %override;
our @remap_lines;
our @ftp_remap_lines;
our @filter_lines;
our @ipnat_lines;
my @user_info = getpwuid $UID;
my $default_user = $user_info[0];
#####################################
# #
# Finding the ethernet interface #
# #
#####################################
# Defaults in case we can't access ifconfig
our %default_interface =
(
"solaris" => "hme0",
"dec_osf" => "tu0",
"irix" => "ef0",
"freebsd" => "de0",
"linux" => "eth0",
"hpux" => "lan0"
);
sub get_default_if {
my $dif = $default_interface{$OSNAME};
if (! $dif) {
die "Unknown OS type, could determine default internface\n";
}
return $dif;
}
sub process_if_record {
my ($if_name, $if_info) = @_;
if ($if_name eq "") {
return 0;
}
# Do not return loop back addrs
if ($if_name =~ /^lo/) {
return 0;
}
# Check to see if the address has an address
if ($if_info =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/) {
# If it's not localhost, it's good enough
if ($1 != 127 || $2 == 0 || $3 == 0 || $4 == 1) {
return 1;
}
}
return 0;
}
sub find_ethernet_if {
if (!open(IFCONFIG, "ifconfig -a |") &&
!open(IFCONFIG, "/usr/sbin/ifconfig -a |")) {
warn "Warning: Could not open ifconfig : $! : guessing interface\n";
return get_default_if();
}
# Basic strategy is loop over the interfaces and use the first
# one that is up that is not localhost
#
# Between the various OS's there are several different formats
# for ifconfig output. They have in common that interfaces
# start the line with "<if_name>:" Some put new line between
# interfaces and others do not
my $if_name = "";
my $if_info = "";
my $tmp;
my $done;
while ($tmp = <IFCONFIG>) {
chomp($tmp);
if ($tmp =~ /^(\w+):(.*)/) {
# We've got a new record, process old info
my $new_name = $1;
my $new_info = $2;
if (process_if_record($if_name, $if_info)) {
return $if_name;
}
$if_name = $new_name;
$if_info = $new_info;
} elsif ($tmp =~ /^\s*$/) {
# Blank lines tell us the old record is done
if (process_if_record($if_name, $if_info)) {
return $if_name;
}
$if_name = "";
$if_info = "";
} else {
$if_info = $if_info . " " . $tmp;
}
}
if (process_if_record($if_name, $if_info)) {
return $if_name;
}
return get_default_if;
}
my $eth_if = find_ethernet_if();
###############*######################
# #
# End: finding ethernet interface #
# #
######################################
our %defaults =
(
"proxy.config.socks.socks_server_port" => 1080,
"proxy.config.proxy_name" => "ink-proxy.inktomi.com",
"proxy.config.bin_path" => "bin",
"proxy.config.alarm_email" => $default_user,
"proxy.config.cluster.mc_group_addr" => "225.0.1.89",
"proxy.config.admin.html_doc_root" => "ui",
"proxy.config.admin.admin_user" => "admin",
"proxy.config.admin.admin_password" => "21232F297A57A5A743894A0",
"proxy.config.admin.user_id" => $default_user,
"proxy.config.http.ftp.anonymous_passwd" => $eth_if,
"proxy.config.net.connections_throttle" => 8000,
"proxy.config.cluster.ethernet_interface" => $eth_if,
"proxy.config.icp.icp_interface" => $eth_if,
"proxy.config.hostdb.size" => 200000,
"proxy.config.rni.server_port" => 7802,
"proxy.config.reverse_proxy.enabled" => 0,
"proxy.config.loadshedding.max_connections" => 0,
"proxy.config.rni.proxy_rtsp_port" => 6060,
"proxy.config.raf.enabled" => 1
);
our %export_ports =
(
"proxy.config.http.server_port" => "tsHttpPort",
"proxy.config.raf.port" => "rafPort",
"proxy.config.ftp.proxy_server_port" => "tsFtpPort",
"proxy.config.mixt.rtsp_proxy_port" => "tsRtspPort",
"proxy.config.wmt.port" => "tsWmtPort",
"proxy.config.rni.proxy_port" => "tsRniPort"
);
our %base_port_hash =
(
"proxy.config.http.server_port" => 0,
"proxy.config.admin.web_interface_port" => 2,
"proxy.config.admin.overseer_port" => 3,
"proxy.config.admin.autoconf_port" => 4,
"proxy.config.process_manager.mgmt_port" => 5,
"proxy.config.log2.collation_port" => 7,
"proxy.config.cluster.cluster_port" => 8,
"proxy.config.cluster.rsport" => 10,
"proxy.config.cluster.mcport" => 11,
"proxy.config.rni.client_port" => 12,
"proxy.config.mixt.rtsp_proxy_port" => 13,
"proxy.config.rni.proxy_port" => 14,
"proxy.config.raf.port" => 15,
"proxy.config.raf.manager.port" => 16,
"proxy.config.wmt.port" => 17,
"proxy.config.ftp.proxy_server_port" => 18,
"proxy.config.nntp.server_port" => 19
);
our %config_meta = ();
sub process_records_blob {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
}
my ($cmd, $arg1, $arg2, $arg3, $arg4) = split(/\s+/, $line, 5);
if ($cmd eq "base_port") {
$base_port = $arg1;
} elsif ($cmd eq "add") {
my $config_entry = $arg1 . " " . $arg2 . " " . $arg3 . " " . $arg4;
push @additional_config_entries, $config_entry;
} else {
$override{$cmd} = $arg1;
}
}
return "";
}
sub process_remap_config {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
} else {
push(@remap_lines, $line);
}
}
return "";
}
sub process_ftp_remap_config {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
} else {
push(@ftp_remap_lines, $line);
}
}
return "";
}
sub process_filter_config {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
} else {
push(@filter_lines, $line);
}
}
return "";
}
sub process_ipnat_conf {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
} else {
push(@ipnat_lines, $line);
}
}
return "";
}
sub process_meta_config {
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
return $1;
} else {
if ($line =~ /(\S+):\s+(\S+)/) {
print "meta config '$1' = '$2'\n";
$config_meta{$1} = $2;
} elsif ($line !~ /^\s*$/) {
warn("Malformed meta config: $line\n");
}
}
}
return "";
}
sub process_other_file_blob {
my ($file_name) = @_;
my $file_path = $run_dir . "/etc/trafficserver/" . $file_name;
open(OTHER_FILE, "> $file_path") || die "Failed to write file $file_name: $!\n";
my $line;
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
close(OTHER_FILE);
return $1;
}
print OTHER_FILE $line;
}
close (OTHER_FILE);
return "";
};
sub read_test_config_blob {
my ($test_config_blob) = @_;
open (CONFIG_BLOB, "< $test_config_blob") || die "Failed to open config_blob: $!\n";
my $line;
my $file_name = "";
while ($line = <CONFIG_BLOB>) {
if ($line =~ /^\[([^\]]*)\]\s*$/) {
$file_name= $1;
last;
}
}
while ($file_name ne "") {
if ($file_name eq "records.config") {
$file_name = process_records_blob();
} elsif ($file_name eq "remap.config") {
$file_name = process_remap_config();
} elsif ($file_name eq "ftp_remap.config") {
$file_name = process_ftp_remap_config();
} elsif ($file_name eq "filter.config") {
$file_name = process_filter_config();
} elsif ($file_name eq "ipnat.conf") {
$file_name = process_ipnat_conf();
} elsif ($file_name eq "meta") {
$file_name = process_meta_config();
} else {
# any other file is writting to config
$file_name = process_other_file_blob($file_name);
}
}
close (CONFIG_BLOB);
}
my %records_seen = {};
sub output_records_config {
my ($records_config_in, $records_config_out, $port_start) = @_;
open (RECORDS_IN, "< $records_config_in") ||
die "Couldn't open $records_config_in: $!\n";
open (RECORDS_OUT, "> $records_config_out") ||
die "Couldn't open $records_config_out: $!\n";
my $rec_line;
my $num_ports_alloc = 0;
while($rec_line = <RECORDS_IN>) {
my $new_line;
if ($rec_line =~ /^\s*#/) {
$new_line = $rec_line;
} else {
my $changed = 0;
my $tmp;
my ($r_class, $r_name, $r_type, $r_val) = split (/\s+/, $rec_line, 4);
# Look at defaults
if (defined($tmp = $defaults{$r_name})) {
$r_val = $tmp;
$changed = 1;
}
# Look at the port stuff
if (defined($tmp = $base_port_hash{$r_name})) {
$r_val = $port_start + $num_ports_alloc;
$changed = 1;
$num_ports_alloc++;
}
# Look at rc overrides
if (defined($tmp = $override{$r_name})) {
$r_val = $tmp;
$changed = 1;
}
$records_seen{$r_name} = $r_val;
if ($changed) {
$new_line = $r_class . " " . $r_name . " " . "$r_type" . " " . "$r_val" . "\n";
} else {
$new_line = $rec_line;
}
}
print RECORDS_OUT $new_line;
}
close(RECORDS_IN);
my $config_entry;
foreach $config_entry (@additional_config_entries) {
my ($r_class, $r_name, $r_type, $r_val) = split (/\s+/, $config_entry, 4);
if ($records_seen{$r_name}) {
# We already has an entry for this record so ignore the addition
next;
}
if ($r_val eq "<alloc_port>") {
my $tmp;
if (defined($tmp = $base_port_hash{$r_name})) {
$r_val = $num_ports_alloc + $port_start;
$config_entry = $r_class . " " . $r_name . " " . "$r_type" . " " . "$r_val" . "\n";
$num_ports_alloc++;
}
}
$records_seen{$r_name} = $r_val;
print RECORDS_OUT $config_entry . "\n";
}
close(RECORDS_OUT);
return $num_ports_alloc;
}
sub output_remap_config {
my $remap_file = $run_dir . "/etc/trafficserver/remap.config";
open(REMAP_FILE, "> $remap_file") || die "Failed to write file $remap_file: $!\n";
my $line;
while ($line = shift(@remap_lines)) {
chomp($line);
my $output_line = "";
while ($line) {
if ($line =~ /([^\(]*)&&\(([^\)]+)\)(.*)/) {
$output_line = $output_line . $1;
my $rec_var = $2;
if ($records_seen{$rec_var}) {
$output_line = $output_line . $records_seen{$rec_var};
} else {
$output_line = $output_line . "&&(" . $2 . ")";
}
$line = $3;
} else {
$output_line = $output_line . $line;
$line = "";
}
}
print REMAP_FILE "$output_line\n";
}
close(REMAP_FILE);
}
sub output_ftp_remap_config {
my $ftp_remap_file = $run_dir . "/etc/trafficserver/ftp_remap.config";
open(REMAP_FILE, "> $ftp_remap_file") || die "Failed to write file $ftp_remap_file: $!\n";
my $line;
while ($line = shift(@ftp_remap_lines)) {
chomp($line);
my $output_line = "";
while ($line) {
if ($line =~ /([^\(]*)&&\(([^\)]+)\)(.*)/) {
$output_line = $output_line . $1;
my $rec_var = $2;
if ($records_seen{$rec_var}) {
$output_line = $output_line . $records_seen{$rec_var};
} else {
$output_line = $output_line . "&&(" . $2 . ")";
}
$line = $3;
} else {
$output_line = $output_line . $line;
$line = "";
}
}
print REMAP_FILE "$output_line\n";
}
close(REMAP_FILE);
}
sub output_ipnat_conf {
my $ipnat_file = $run_dir . "/etc/trafficserver/ipnat.conf";
open(IPNAT_FILE, "> $ipnat_file") || die "Failed to write file $ipnat_file: $!\n";
my $line;
while ($line = shift(@ipnat_lines)) {
chomp($line);
my $output_line = "";
while ($line) {
if ($line =~ /([^\(]*)&&\(([^\)]+)\)(.*)/) {
$output_line = $output_line . $1;
my $rec_var = $2;
if ($records_seen{$rec_var}) {
$output_line = $output_line . $records_seen{$rec_var};
} else {
$output_line = $output_line . "&&(" . $2 . ")";
}
$line = $3;
} else {
$output_line = $output_line . $line;
$line = "";
}
}
print IPNAT_FILE "$output_line\n";
}
close(IPNAT_FILE);
}
sub output_filter_config {
my $filter_file = $run_dir . "/etc/trafficserver/filter.config";
open(FILTER_FILE, "> $filter_file") || die "Failed to write file $filter_file: $!\n";
my $line;
while ($line = shift(@filter_lines)) {
chomp($line);
my $output_line = "";
while ($line) {
if ($line =~ /([^\(]*)&&\(eval(.)(.*)\2\)(.*)/) {
$output_line = $output_line . $1;
# print "eval|" . $3 . "|\n";
my $tmp = eval $3;
$output_line = $output_line . $tmp;
$line = $4;
} elsif ($line =~ /([^\(]*)&&\(([^\)]+)\)(.*)/) {
$output_line = $output_line . $1;
my $rec_var = $2;
if ($records_seen{$rec_var}) {
$output_line = $output_line . $records_seen{$rec_var};
} else {
$output_line = $output_line . "&&(" . $2 . ")";
}
$line = $3;
} else {
$output_line = $output_line . $line;
$line = "";
}
}
print FILTER_FILE "$output_line\n";
}
close(FILTER_FILE);
}
sub build_port_bindings {
my ($records_config) = @_;
my $output_line = "port_binding:";
open (RECORDS, "< $records_config") ||
die "Couldn't open $records_config: $!\n";
my $rec_line;
while($rec_line = <RECORDS>) {
if ($rec_line !~ /^\s*#/) {
my ($r_class, $r_name, $r_type, $r_val) = split (/\s+/, $rec_line);
if ($export_ports{$r_name}) {
$output_line = $output_line . " " . $export_ports{$r_name} . " " . $r_val;
}
}
}
return $output_line;
}
our @lib_ldap_locations =
(
"bin",
"lib",
"f_pkg/lib"
);
our @populate_dirs = ( "bin", "etc/trafficserver", "etc/trafficserver/internal", "logs");
our %populate_symlinks =
( "bin/traffic_server" => "bin/traffic_server",
"bin/traffic_manager" => "bin/traffic_manager",
"bin/traffic_cop" => "bin/traffic_cop",
"bin/traffic_line" => "bin/traffic_line",
"bin/start_traffic_server" => "bin/start_traffic_server",
"bin/stop_traffic_server" => "bin/stop_traffic_server",
"bin/filter_to_policy" => "bin/filter_to_policy",
"etc/trafficserver/body_factory" => "etc/trafficserver/body_factory",
"etc/trafficserver/plugins" => "etc/trafficserver/plugins",
"lib" => "lib",
"ui" => "ui"
);
our %populate_exclude_config =
(
"records.config" => 1,
"records.config.shadow" => 1,
"storage.config.shadow" => 1
);
# not really needed, the ldap lib is now always in $rundir/lib/
sub find_ldap_lib() {
my $ldap_lib = "libldapssl40.so";
my @tmp = @lib_ldap_locations;
my $look_here;
while ($look_here = shift(@tmp)) {
my $check_path = $bin_dir . "/" . $look_here . "/" . $ldap_lib;
if ( -r $check_path ) {
my $from_key = $look_here . "/" . $ldap_lib;
my $to_value = "bin/" . $ldap_lib;
# Found the library
$populate_symlinks{$from_key} = $to_value;
return;
}
}
warn("Could not find $ldap_lib\n");
}
sub populate_run_dir() {
my ($dir, $from_file_key);
foreach $dir (@populate_dirs) {
my $rdir = $run_dir . "/" . $dir;
if (! -d $rdir) {
mkdir($rdir);
}
}
foreach $from_file_key (keys (%populate_symlinks)) {
my $from_file = $bin_dir . "/" . $from_file_key;
my $to_file = $run_dir . "/" . $populate_symlinks{$from_file_key};
if (! -e $to_file && ! -l $to_file) {
symlink($from_file, $to_file);
}
}
my $config_dir_source = $bin_dir . "/etc/trafficserver";
my $config_dir_target = $run_dir . "/etc/trafficserver";
opendir(CONFIG_SOURCE_DIR, $config_dir_source) ||
die "Couldn't open config src dir: $!\n";
my $dir_ent;
while ($dir_ent = readdir(CONFIG_SOURCE_DIR)) {
if (! $populate_exclude_config{$dir_ent}) {
my $source_file = $config_dir_source . "/" . $dir_ent;
if (-f $source_file) {
my $target_file = $config_dir_target . "/" . $dir_ent;
copy($source_file, $target_file) || die "Copy of $dir_ent failed: $!\n";
}
}
}
}
open(OUTPUT,">&=$ARGV[1]") || die "Couldn't open output: $!";
my $tmp;
my %input_args;
while ($tmp = <STDIN>) {
print $tmp;
if ($tmp =~ /^([^:]+):\s(.*)\n/) {
$input_args{$1} = $2;
}
}
my $records_config_in = "";
$bin_dir = $input_args{"bin_dir"};
if ($bin_dir) {
$records_config_in = $bin_dir . "/etc/trafficserver/records.config";
} else {
warn("bin_dir not sent\n");
exit(1);
}
$run_dir = $input_args{"run_dir"};
my $no_run_dir = $input_args{"no_run_dir"};
my $records_config_out;
if ($no_run_dir) {
$records_config_out = $bin_dir . "/etc/trafficserver/records.config.shadow";
$run_dir = $bin_dir;
} else {
$records_config_out = $run_dir . "/etc/trafficserver/records.config";
}
if (!$run_dir) {
warn("run_dir not sent\n");
exit(1);
}
if (! $no_run_dir) {
# find_ldap_lib();
populate_run_dir();
}
my $ports = $input_args{"ports_avail"};
my $config_blob = $input_args{"config_file"};
if (!$config_blob) {
die("config_blob not sent\n");
}
read_test_config_blob($config_blob);
my ($start_port, $end_port);
if ($ports =~ /^(\d+)-(\d+)/) {
$start_port = $1;
$end_port = $2;
} else {
warn("ports_avail invalid\n");
}
my $use_start_port = $base_port;
if ($use_start_port == 0) {
$use_start_port = $start_port;
}
my $ports_used;
$ports_used = output_records_config($records_config_in,
$records_config_out, $use_start_port);
if (scalar(@remap_lines) > 0) {
output_remap_config();
}
if (scalar(@ftp_remap_lines) > 0) {
output_ftp_remap_config();
}
if (scalar(@filter_lines) > 0) {
output_filter_config();
}
if (scalar(@ipnat_lines) > 0) {
output_ipnat_conf();
}
my $cmd_line = "cmd_line: $bin_dir/bin/";
if ($config_meta{"run_manager"}) {
$cmd_line = $cmd_line . "traffic_manager";
} else {
$cmd_line = $cmd_line . "traffic_server";
}
if ($use_start_port == $start_port) {
print OUTPUT "ports_used: $ports_used\n";
}
my $bindings = build_port_bindings($records_config_out);
print OUTPUT $bindings . "\n";
print OUTPUT $cmd_line . "\n";
#
# We need to set the LD_LIBRARY_PATH for dealing with
# the ldap.so shared object
#
my $ld_lib_path = $ENV{"LD_LIBRARY_PATH"};
if ($ld_lib_path eq "") {
$ld_lib_path = $run_dir . "/bin";
$ld_lib_path .= $run_dir . "/lib";
} else {
$ld_lib_path = $ld_lib_path . ":" . $run_dir . "/bin";
$ld_lib_path .= $ld_lib_path . ":" . $run_dir . "/lib";
}
print OUTPUT "env_vars: LD_LIBRARY_PATH=" . $ld_lib_path . "\n";
exit(0);