You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2017/01/27 16:53:55 UTC

[34/36] incubator-trafficcontrol git commit: Removed global vars and made many minor improvements

Removed global vars and made many minor improvements


Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/230aa7c0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/230aa7c0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/230aa7c0

Branch: refs/heads/master
Commit: 230aa7c0735312d0a35c1f76f8ca5f1991640368
Parents: d775c03
Author: peter.w.ryder <pe...@gmail.com>
Authored: Thu Jan 12 15:10:00 2017 -0500
Committer: Dan Kirkwood <da...@gmail.com>
Committed: Fri Jan 27 09:52:53 2017 -0700

----------------------------------------------------------------------
 traffic_ops/install/bin/postinstall       | 293 +++++++++++----------
 traffic_ops/install/lib/BuildPerlDeps.pm  |  32 ++-
 traffic_ops/install/lib/GenerateCert.pm   |  26 +-
 traffic_ops/install/lib/InstallUtils.pm   |  21 +-
 traffic_ops/install/lib/ProfileCleanup.pm | 199 +++++++++------
 traffic_ops/install/lib/WebDep.pm         | 337 +++++++++++++------------
 6 files changed, 493 insertions(+), 415 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/bin/postinstall
----------------------------------------------------------------------
diff --git a/traffic_ops/install/bin/postinstall b/traffic_ops/install/bin/postinstall
index 1092338..2f6f3d7 100755
--- a/traffic_ops/install/bin/postinstall
+++ b/traffic_ops/install/bin/postinstall
@@ -25,53 +25,66 @@ use Safe;
 use POSIX;
 use File::Basename qw{dirname};
 use File::Path qw{make_path};
-use InstallUtils qw{ :all };
-use BuildPerlDeps qw{ :all };
-use GenerateCert qw{ :all };
-use ProfileCleanup qw { :all };
 use Digest::SHA1 qw(sha1_hex);
 use Data::Dumper qw(Dumper);
 use Scalar::Util qw(looks_like_number);
 use Getopt::Long;
 
+use InstallUtils;
+use BuildPerlDeps;
+use GenerateCert qw{ :all };
+use ProfileCleanup;
+
 # paths of the output configuration files
-our $databaseConfFile = "/opt/traffic_ops/app/conf/production/database.conf";
-our $dbConfFile       = "/opt/traffic_ops/app/db/dbconf.yml";
-our $cdnConfFile      = "/opt/traffic_ops/app/conf/cdn.conf";
-our $ldapConfFile     = "/opt/traffic_ops/app/conf/ldap.conf";
-our $usersConfFile    = "/opt/traffic_ops/install/data/json/users.json";
-our $profilesConfFile = "/opt/traffic_ops/install/data/profiles/";
-our $opensslConfFile  = "/opt/traffic_ops/install/data/json/openssl_configuration.json";
-our $paramConfFile    = "/opt/traffic_ops/install/data/json/profiles.json";
+my $databaseConfFile = "/opt/traffic_ops/app/conf/production/database.conf";
+my $dbConfFile       = "/opt/traffic_ops/app/db/dbconf.yml";
+my $cdnConfFile      = "/opt/traffic_ops/app/conf/cdn.conf";
+my $ldapConfFile     = "/opt/traffic_ops/app/conf/ldap.conf";
+my $usersConfFile    = "/opt/traffic_ops/install/data/json/users.json";
+my $profilesConfFile = "/opt/traffic_ops/install/data/profiles/";
+my $opensslConfFile  = "/opt/traffic_ops/install/data/json/openssl_configuration.json";
+my $paramConfFile    = "/opt/traffic_ops/install/data/json/profiles.json";
 
-our $profile_dir       = "/opt/traffic_ops/install/data/profiles/";
-our $post_install_cfg = "/opt/traffic_ops/install/data/json/post_install.json";
+my $custom_profile_dir = $profilesConfFile . "custom";
 
-our $reconfigure_defaults = "/opt/traffic_ops/.reconfigure_defaults";
+# stores parameters for traffic ops config
+my $parameters;
 
-our $parameters;
+# location of traffic ops profiles
+my $profileDir       = "/opt/traffic_ops/install/data/profiles/";
+my $post_install_cfg = "/opt/traffic_ops/install/data/json/post_install.json";
 
-# old way of reconfiguring postinstall - only here to check for file and let user know it is deprecated
-my $reconfigure_file = "/opt/traffic_ops/.reconfigure";
+# log file for the installer
+my $logFile = "/var/log/traffic_ops/postinstall.log";
+
+# debug mode
+my $debug   = 0;
+
+# log file for cpan output
+my $cpanLogFile = "/var/log/traffic_ops/cpan.log";
 
 # whether or not to reconfigure traffic ops
-my $reconfigure;
+my $reconfigure = 0;
 
-# whether to create a config file with default values
-my $dumpDefaults;
+# used to check for .reconfigure_defaults file for backwards compatability
+my $reconfigure_defaults = "/opt/traffic_ops/.reconfigure_defaults";
 
-# log file for the installer
-our $logFile = "/var/log/traffic_ops/postinstall.log";
+# old way of reconfiguring postinstall - only here to check for file and let user know it is deprecated
+my $reconfigure_file = "/opt/traffic_ops/.reconfigure";
 
 # maximum size the uncompressed log file should be before rotating it - rotating it copies the current log
 #  file to the same name appended with .bkp replacing the old backup if any is there
-my $maxLogSize = 1000000;    #bytes
+my $maxLogSize = 10000000;    #bytes
 
-# log file for cpan - this log becomes large and is rotated every install
-our $cpanLogFile = "/var/log/traffic_ops/cpan.log";
+# whether to create a config file with default values
+my $dumpDefaults;
 
 # configuration file output with answers which can be used as input to postinstall
-our $outputConfigFile = "/var/log/traffic_ops/configuration_file.json";
+my $outputConfigFile = "/opt/traffic_ops/install/bin/configuration_file.json";
+
+my $inputFile = "";
+my $automatic = 0;
+my $defaultInputs;
 
 sub getDbDriver {
     return "mymysql";
@@ -105,7 +118,7 @@ sub getField {
     my $hidden        = shift;
 
     # if there is no config file and not in automatic mode prompt for all questions with default answers
-    if ( !$::inputFile && !$::automatic ) {
+    if ( !$inputFile && !$automatic ) {
 
         # if hidden then dont show password in terminal
         if ($hidden) {
@@ -132,10 +145,10 @@ sub getConfig {
     my %config;
 
     if ( !defined $userInput->{$fileName} ) {
-        logger( "No $fileName found in config", "error" );
+        InstallUtils::logger( "No $fileName found in config", "error" );
     }
 
-    logger( "===========$fileName===========", "info" );
+    InstallUtils::logger( "===========$fileName===========", "info" );
 
     foreach my $var ( @{ $userInput->{$fileName} } ) {
         my $question = getConfigQuestion($var);
@@ -144,7 +157,7 @@ sub getConfig {
 
         $config{ $var->{"config_var"} } = $answer;
         if ( !$hidden ) {
-            logger( "$question:  $answer", "info" );
+            InstallUtils::logger( "$question:  $answer", "info" );
         }
     }
     return %config;
@@ -164,8 +177,8 @@ sub generateDbConf {
     my %dbconf = getConfig( $userInput, $dbFileName );
     $dbconf{"description"} = "$dbconf{type} database on $dbconf{hostname}:$dbconf{port}";
     make_path( dirname($dbFileName), { mode => 0755 } );
-    writeJson( $dbFileName, \%dbconf );
-    logger( "Database configuration has been saved", "info" );
+    InstallUtils::writeJson( $dbFileName, \%dbconf );
+    InstallUtils::logger( "Database configuration has been saved", "info" );
 
     # broken out into separate file/config area
     my %todbconf = getConfig( $userInput, $toDBFileName );
@@ -191,22 +204,22 @@ sub generateCdnConf {
 
     my %cdnConfiguration = getConfig( $userInput, $fileName );
 
-    # First,  read existing one -- already loaded with a bunch of stuff
+    # First, read existing one -- already loaded with a bunch of stuff
     my $cdnConf;
     if ( -f $fileName ) {
         $cdnConf = Safe->new->rdo($fileName) or errorOut("Error loading $fileName: $@");
     }
     if ( lc $cdnConfiguration{genSecret} =~ /^y(?:es)?/ ) {
         my @secrets   = @{ $cdnConf->{secrets} };
-        my $newSecret = randomWord();
-        unshift @secrets, randomWord();
+        my $newSecret = InstallUtils::randomWord();
+        unshift @secrets, InstallUtils::randomWord();
         if ( $cdnConfiguration{keepSecrets} > 0 && $#secrets > $cdnConfiguration{keepSecrets} - 1 ) {
 
             # Shorten the array to requested length
             $#secrets = $cdnConfiguration{keepSecrets} - 1;
         }
     }
-    writePerl( $fileName, $cdnConf );
+    InstallUtils::writePerl( $fileName, $cdnConf );
 }
 
 # userInput: The entire input config file which is either user input or the defaults
@@ -221,14 +234,14 @@ sub generateLdapConf {
     my $useLdap = $userInput->{$fileName}[0]->{"Do you want to set up LDAP?"};
 
     if ( !lc $useLdap =~ /^y(?:es)?/ ) {
-        logger( "Not setting up ldap", "info" );
+        InstallUtils::logger( "Not setting up ldap", "info" );
         return;
     }
 
     my %ldapConf = getConfig( $userInput, $fileName );
 
     make_path( dirname($fileName), { mode => 0755 } );
-    writeJson( $fileName, \%ldapConf );
+    InstallUtils::writeJson( $fileName, \%ldapConf );
 }
 
 sub generateUsersConf {
@@ -241,7 +254,7 @@ sub generateUsersConf {
     $user{username} = $config{tmAdminUser};
     $user{password} = sha1_hex( $config{tmAdminPw} );
 
-    writeJson( $fileName, \%user );
+    InstallUtils::writeJson( $fileName, \%user );
     $user{password} = $config{tmAdminPw};
     return \%user;
 }
@@ -258,16 +271,16 @@ sub generateOpenSSLConf {
     my $fileName  = shift;
 
     if ( !defined $userInput->{$fileName} ) {
-        logger( "No OpenSSL Configuration - questions will be asked", "info" );
+        InstallUtils::logger( "No OpenSSL Configuration - questions will be asked", "info" );
 
         # write an empty config so openssl does not use an old file
-        writeJson( $fileName, my %emptyConfig );
+        InstallUtils::writeJson( $fileName, my %emptyConfig );
         return;
     }
 
     my %config = getConfig( $userInput, $fileName );
 
-    writeJson( $fileName, \%config );
+    InstallUtils::writeJson( $fileName, \%config );
     return \%config;
 }
 
@@ -276,14 +289,14 @@ sub generateParamConf {
     my $fileName  = shift;
 
     my %config = getConfig( $userInput, $fileName );
-    writeJson( $fileName, \%config );
+    InstallUtils::writeJson( $fileName, \%config );
     return \%config;
 }
 
 # check default values for missing config_var parameter
 sub sanityCheckDefaults {
-    foreach my $file ( ( keys $::defaultInputs ) ) {
-        foreach my $defaultValue ( @{ $::defaultInputs->{$file} } ) {
+    foreach my $file ( ( keys $defaultInputs ) ) {
+        foreach my $defaultValue ( @{ $defaultInputs->{$file} } ) {
             my $question = getConfigQuestion($defaultValue);
 
             if ( !defined $defaultValue->{"config_var"}
@@ -304,13 +317,13 @@ sub sanityCheckConfig {
     my $userInput = shift;
     my $diffs     = 0;
 
-    foreach my $file ( ( keys $::defaultInputs ) ) {
+    foreach my $file ( ( keys $defaultInputs ) ) {
         if ( !defined $userInput->{$file} ) {
-            logger( "File '$file' found in defaults but not config file", "warn" );
+            InstallUtils::logger( "File '$file' found in defaults but not config file", "warn" );
             $userInput->{$file} = [];
         }
 
-        foreach my $defaultValue ( @{ $::defaultInputs->{$file} } ) {
+        foreach my $defaultValue ( @{ $defaultInputs->{$file} } ) {
 
             my $found = 0;
             foreach my $configValue ( @{ $userInput->{$file} } ) {
@@ -322,21 +335,21 @@ sub sanityCheckConfig {
             # if the question is not found in the config file add it from defaults
             if ( !$found ) {
                 my $question = getConfigQuestion($defaultValue);
-                logger( "Question '$question' found in defaults but not in '$file'", "warn" );
+                InstallUtils::logger( "Question '$question' found in defaults but not in '$file'", "warn" );
 
                 my %temp;
                 my $answer;
                 my $hidden = exists $defaultValue->{"hidden"} && $defaultValue->{"hidden"} ? 1 : 0;
 
                 # in automatic mode add the missing question with default answer
-                if ($::automatic) {
+                if ($automatic) {
                     $answer = $defaultValue->{$question};
-                    logger( "Adding question '$question' with default answer " . ( $hidden ? "" : "'$answer'" ), "info" );
+                    InstallUtils::logger( "Adding question '$question' with default answer " . ( $hidden ? "" : "'$answer'" ), "info" );
                 }
 
                 # in interactive mode prompt the user for answer to missing question
                 else {
-                    logger( "Prompting user for answer", "info" );
+                    InstallUtils::logger( "Prompting user for answer", "info" );
                     if ($hidden) {
                         $answer = promptPasswordVerify($question);
                     }
@@ -361,7 +374,7 @@ sub sanityCheckConfig {
         }
     }
 
-    logger( "File sanity check complete - found $diffs difference" . ( $diffs == 1 ? "" : "s" ), "info" );
+    InstallUtils::logger( "File sanity check complete - found $diffs difference" . ( $diffs == 1 ? "" : "s" ), "info" );
 }
 
 # A function which returns the default inputs data structure. These questions and answers will be used if there is no
@@ -369,7 +382,7 @@ sub sanityCheckConfig {
 
 sub getDefaults {
     return {
-        $::databaseConfFile => [
+        $databaseConfFile => [
             {
                 "Database type" => "mysql",
                 "config_var"    => "type"
@@ -396,7 +409,7 @@ sub getDefaults {
                 "hidden"                                 => "true"
             }
         ],
-        $::dbConfFile => [
+        $dbConfFile => [
             {
                 "Database server root (admin) user" => "root",
                 "config_var"                        => "dbAdminUser"
@@ -407,7 +420,7 @@ sub getDefaults {
                 "hidden"                             => "true"
             }
         ],
-        $::cdnConfFile => [
+        $cdnConfFile => [
             {
                 "Generate a new secret?" => "yes",
                 "config_var"             => "genSecret"
@@ -417,7 +430,7 @@ sub getDefaults {
                 "config_var"                 => "keepSecrets"
             }
         ],
-        $::ldapConfFile => [
+        $ldapConfFile => [
             {
                 "Do you want to set up LDAP?" => "no",
                 "config_var"                  => "setupLdap"
@@ -440,7 +453,7 @@ sub getDefaults {
                 "config_var"       => "search_base"
             }
         ],
-        $::usersConfFile => [
+        $usersConfFile => [
             {
                 "Administration username for Traffic Ops" => "admin",
                 "config_var"                              => "tmAdminUser"
@@ -451,8 +464,8 @@ sub getDefaults {
                 "hidden"                      => "true"
             }
         ],
-        $::profilesConfFile => [],
-        $::opensslConfFile  => [
+        $profilesConfFile => [],
+        $opensslConfFile  => [
             {
                 "Do you want to generate a certificate?" => "yes",
                 "config_var"                             => "genCert"
@@ -487,7 +500,7 @@ sub getDefaults {
                 "hidden"         => "true"
             }
         ],
-        $::paramConfFile => [
+        $paramConfFile => [
             {
                 "Traffic Ops url" => "https://localhost",
                 "config_var"      => "tm.url"
@@ -550,61 +563,61 @@ sub setupDatabase {
     #
     # Call mysql initialization script.
     #
-    logger( "Creating database with user: $todbconf->{dbAdminUser}", "info" );
-    my $result = execCommand( "/opt/traffic_ops/install/bin/create_db", $todbconf->{dbAdminUser}, $todbconf->{dbAdminPw} );
+    InstallUtils::logger( "Creating database with user: $todbconf->{dbAdminUser}", "info" );
+    my $result = InstallUtils::execCommand( "/opt/traffic_ops/install/bin/create_db", $todbconf->{dbAdminUser}, $todbconf->{dbAdminPw} );
     if ( $result != 0 ) {
         errorOut("Failed to create the database");
     }
 
-    logger( "Setting up database", "info" );
+    InstallUtils::logger( "Setting up database", "info" );
     chdir("/opt/traffic_ops/app");
-    $result = execCommand( "/usr/bin/perl", "db/admin.pl", "--env=production", "setup" );
+    $result = InstallUtils::execCommand( "/usr/bin/perl", "db/admin.pl", "--env=production", "setup" );
 
     if ( $result != 0 ) {
         errorOut("Database initialization failed");
     }
     else {
-        logger( "Database initialization succeeded", "info" );
+        InstallUtils::logger( "Database initialization succeeded", "info" );
     }
 
-    $result = execCommand( "/opt/traffic_ops/install/bin/dataload", $todbconf->{dbAdminUser}, $todbconf->{dbAdminPw} );
+    $result = InstallUtils::execCommand( "/opt/traffic_ops/install/bin/dataload", $todbconf->{dbAdminUser}, $todbconf->{dbAdminPw} );
     if ( $result != 0 ) {
-        logger( "Failed to load seed data", "error" );
+        InstallUtils::logger( "Failed to load seed data", "error" );
     }
 
-    logger( "Downloading MaxMind data", "info" );
+    InstallUtils::logger( "Downloading MaxMind data", "info" );
     chdir("/opt/traffic_ops/app/public/routing");
-    $result = execCommand("/usr/bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz");
+    $result = InstallUtils::execCommand("/usr/bin/wget http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz");
     if ( $result != 0 ) {
-        logger( "Failed to download MaxMind data", "error" );
+        InstallUtils::logger( "Failed to download MaxMind data", "error" );
     }
 
-    logger( "Copying coverage zone file to public dir", "info" );
-    $result = execCommand("/bin/mv /opt/traffic_ops/app/public/coverage-zone.json .");
+    InstallUtils::logger( "Copying coverage zone file to public dir", "info" );
+    $result = InstallUtils::execCommand("/bin/mv /opt/traffic_ops/app/public/coverage-zone.json .");
     if ( $result != 0 ) {
-        logger( "Failed to copy coverage zone file", "error" );
+        InstallUtils::logger( "Failed to copy coverage zone file", "error" );
     }
 
     if ( lc $genCert =~ /^y(?:es)?/ ) {
         if ( -x "/usr/bin/openssl" ) {
-            logger( "Installing SSL Certificates", "info" );
+            InstallUtils::logger( "Installing SSL Certificates", "info" );
             $result = GenerateCert::createCert($opensslconf);
 
             if ( $result != 0 ) {
                 errorOut("SSL Certificate Installation failed");
             }
             else {
-                logger( "SSL Certificates have been installed", "info" );
+                InstallUtils::logger( "SSL Certificates have been installed", "info" );
             }
         }
         else {
-            logger( "Unable to install SSL certificates as openssl is not installed",                                     "error" );
-            logger( "Install openssl and then run /opt/traffic_ops/install/bin/generateCert to install SSL certificates", "error" );
+            InstallUtils::logger( "Unable to install SSL certificates as openssl is not installed",                                     "error" );
+            InstallUtils::logger( "Install openssl and then run /opt/traffic_ops/install/bin/generateCert to install SSL certificates", "error" );
             exit 4;
         }
     }
     else {
-        logger("Not generating openssl certification", "info");
+        InstallUtils::logger( "Not generating openssl certification", "info" );
     }
 }
 
@@ -612,17 +625,15 @@ sub setupDatabase {
 # -a         - Automatic mode:   If there are questions in the config file which do not have answers, the script
 #                                will look to the defaults for the answer. If the answer is not in the defaults
 #                                the script will exit
-# -r         - Reconfigure:      Whether or not to reconfigure the database and check perl dependencies - This will rereate the database
+# -r         - Reconfigure:      Whether or not to reconfigure the database and check perl dependencies - This will recreate the database
 # -defaults  - Defaults:         Writes out a configuration file with defaults which can be used as input
 # -debug     - Debug Mode:       More output to the terminal
 # -h         - Help:             Basic command line help menu
 
 sub main {
-    our $inputFile = "";
-    our $automatic = 0;
-    our $debug     = 0;
     my $help = 0;
 
+    # help string
     my $usageString = "Usage: postinstall [-a] [-debug] [-defaults] [-r] -cfile=[config_file]\n";
 
     GetOptions(
@@ -635,11 +646,11 @@ sub main {
     ) or die($usageString);
 
     # stores the default questions and answers
-    our $defaultInputs = getDefaults();
+    $defaultInputs = getDefaults();
 
     if ($help) {
         print $usageString;
-        exit(0);
+        return;
     }
 
     # check if the user running postinstall is root
@@ -647,37 +658,39 @@ sub main {
         errorOut("You must run this script as the root user");
     }
 
+    InstallUtils::initLogger( $debug, $logFile );
+
     if ( -f "$logFile.gz" ) {
-        execCommand( "/bin/gunzip", "$logFile.gz" );
+        InstallUtils::execCommand( "/bin/gunzip", "$logFile.gz" );
     }
 
-    logger( "Starting postinstall", "info" );
+    InstallUtils::logger( "Starting postinstall", "info" );
 
-    logger( "Debug is on", "info" );
+    InstallUtils::logger( "Debug is on", "info" );
 
-    if ($::automatic) {
-        logger( "Running in automatic mode", "info" );
+    if ($automatic) {
+        InstallUtils::logger( "Running in automatic mode", "info" );
     }
 
     # check if the reconfigure_file is present on the system - if it is let the user know its deprecated
     #  and exit with an error
     if ( -f $reconfigure_file ) {
-        logger( "$reconfigure_file file is reprecated - please remove and rerun postinstall", "error" );
+        InstallUtils::logger( "$reconfigure_file file is depreprecated - please remove and rerun postinstall", "error" );
         return;
     }
 
     if ($dumpDefaults) {
-        logger( "Writing default configuration file to $outputConfigFile", "info" );
-        writeJson( $outputConfigFile, $::defaultInputs );
+        InstallUtils::logger( "Writing default configuration file to $outputConfigFile", "info" );
+        InstallUtils::writeJson( $outputConfigFile, $defaultInputs );
         return;
     }
 
-    logger( "Postinstall " . ( defined $reconfigure ? "in" : "not" ) . " in reconfigure mode", "info" );
+    InstallUtils::logger( "Postinstall " . ( defined $reconfigure ? "in" : "not" ) . " in reconfigure mode", "info" );
 
-    rotateLog($cpanLogFile);
+    InstallUtils::rotateLog($cpanLogFile);
 
-    if ( -s $::logFile > $maxLogSize ) {
-        logger( "Postinstall log above max size of $maxLogSize bytes - rotating", "info" );
+    if ( -s $logFile > $maxLogSize ) {
+        InstallUtils::logger( "Postinstall log above max size of $maxLogSize bytes - rotating", "info" );
         rotateLog($logFile);
     }
 
@@ -685,18 +698,18 @@ sub main {
     my $userInput;
 
     # if no input file provided use the defaults
-    if ( $::inputFile eq "" ) {
-        logger( "No input file given - using defaults", "info" );
-        $userInput = $::defaultInputs;
+    if ( $inputFile eq "" ) {
+        InstallUtils::logger( "No input file given - using defaults", "info" );
+        $userInput = $defaultInputs;
     }
     else {
-        logger( "Using input file $::inputFile", "info" );
+        InstallUtils::logger( "Using input file $inputFile", "info" );
 
         # check if the input file exists
-        errorOut("File '$::inputFile' not found") if ( !-f $::inputFile );
+        errorOut("File '$inputFile' not found") if ( !-f $inputFile );
 
         # read and store the input file
-        $userInput = readJson($::inputFile);
+        $userInput = InstallUtils::readJson($inputFile);
     }
 
     # sanity check the defaults if running them automatically
@@ -707,13 +720,13 @@ sub main {
 
     chdir("/opt/traffic_ops/install/bin");
 
-    # if the reconfigure file exists or reconfigure is set then rebuild the perl deps
-    if ( -f $reconfigure_file || $reconfigure ) {
-        my $rc = BuildPerlDeps::build(1);
+    # if reconfigure is set then rebuild the perl deps
+    if ( $reconfigure ) {
+        my $rc = BuildPerlDeps::build( 1, $cpanLogFile );
         if ( $rc != 0 ) {
             errorOut("Failed to install perl dependencies, check the console output and rerun postinstall once you've resolved the error");
         }
-        $rc = execCommand( "./download_web_deps", "-i" );
+        $rc = InstallUtils::execCommand( "./download_web_deps", "-i" );
         if ( $rc != 0 ) {
             errorOut("Failed to install Traffic Ops Web dependencies, check the console output and rerun postinstall once you've resolved the error");
         }
@@ -723,7 +736,7 @@ sub main {
         if ( $rc != 0 ) {
             errorOut("Failed to install perl dependencies, check the console output and rerun postinstall once you've resolved the error");
         }
-        $rc = execCommand( "./download_web_deps", "-i" );
+        $rc = InstallUtils::execCommand( "./download_web_deps", "-i" );
         if ( $rc != 0 ) {
             errorOut("Failed to install Traffic Ops Web dependencies, check the console output and rerun postinstall once you've resolved the error");
         }
@@ -732,48 +745,54 @@ sub main {
     # The generator functions handle checking input/default/automatic mode
 
     # todbconf will be used later when setting up the database
-    my $todbconf = generateDbConf( $userInput, $::databaseConfFile, $::dbConfFile );
-    generateCdnConf( $userInput, $::cdnConfFile );
-    generateLdapConf( $userInput, $::ldapConfFile );
-    my $adminconf = generateUsersConf( $userInput, $::usersConfFile );
-    generateProfilesDir( $userInput, $::profilesConfFile );
-    my $opensslconf = generateOpenSSLConf( $userInput, $::opensslConfFile );
-    my $paramconf = generateParamConf( $userInput, $::paramConfFile );
-
-    # if the reconfigure file exists or the reconfigure command line arg is set then setup the database
-    if ( -f $reconfigure_file || $reconfigure ) {
-        if ($::automatic) {
-            setupDatabase( $todbconf, $::opensslConfFile, $opensslconf->{genCert} );
+    my $todbconf = generateDbConf( $userInput, $databaseConfFile, $dbConfFile );
+    generateCdnConf( $userInput, $cdnConfFile );
+    generateLdapConf( $userInput, $ldapConfFile );
+    my $adminconf = generateUsersConf( $userInput, $usersConfFile );
+    my $custom_profile = generateProfilesDir( $userInput, $profilesConfFile );
+    my $opensslconf = generateOpenSSLConf( $userInput, $opensslConfFile );
+    my $paramconf = generateParamConf( $userInput, $paramConfFile );
+
+    InstallUtils::writeJson( $post_install_cfg, $paramconf );
+
+    # if reconfigure is set then setup the database
+    if ( $reconfigure ) {
+        if ( $automatic ) {
+            setupDatabase( $todbconf, $opensslConfFile, $opensslconf->{genCert} );
         }
         else {
             setupDatabase( $todbconf, 0, $opensslconf->{genCert} );
         }
     }
 
-    # remove the reconfigure file if it exists
-    if ( -f $reconfigure_file ) {
-        logger( "Removing reconfigure file", "info" );
-        unlink($reconfigure_file);
-    }
+    InstallUtils::logger( "Starting Traffic Ops", "info" );
+    InstallUtils::execCommand("/sbin/service traffic_ops start");
+
+    InstallUtils::logger( "Waiting for Traffic Ops to start", "info" );
 
-    logger( "Starting Traffic Ops", "info" );
-    execCommand("/sbin/service traffic_ops start");
+    if (-f $post_install_cfg) {
+        $parameters = InstallUtils::readJson($post_install_cfg);
+    }
 
-    logger( "Waiting for Traffic Ops to start", "info" );
+    if ( !ProfileCleanup::profiles_exist( $adminconf, $paramconf->{"tm.url"}, $parameters, $reconfigure_defaults, $reconfigure ) ) {
+        InstallUtils::logger( "Creating default profiles...", "info" );
+        ProfileCleanup::replace_profile_templates( $paramconf, $adminconf, $post_install_cfg, $parameters, $profileDir );
+        ProfileCleanup::import_profiles( $paramconf->{"tm.url"}, $adminconf, $profileDir );
 
-    if ( !profiles_exist( $adminconf, $paramconf->{"tm.url"} ) ) {
-        logger( "Creating default profiles...", "info" );
-        replace_profile_templates($paramconf);
-        import_profiles($adminconf);
-        profiles_exist( $adminconf, $paramconf->{"tm.url"} );    # call again to create $reconfigure_defaults file if import was successful
+        # call again to create $reconfigure_defaults file if import was successful
+        ProfileCleanup::profiles_exist( $adminconf, $paramconf->{"tm.url"}, $parameters, $reconfigure_defaults, $reconfigure );
     }
     else {
-        logger( "Not creating default profiles", "info" );
+        InstallUtils::logger( "Not creating default profiles", "info" );
+    }
+
+    if ( $custom_profile =~ /^y(?:es)?/ ) {
+        ProfileCleanup::add_custom_profiles( $custom_profile_dir, $adminconf, $parameters->{"tm.url"} );
     }
 
-    logger("Postinstall complete");
+    InstallUtils::logger("Postinstall complete");
 
-    execCommand( "/bin/gzip", "$logFile" );
+    InstallUtils::execCommand( "/bin/gzip", "$logFile" );
 }
 
 main;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/lib/BuildPerlDeps.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/install/lib/BuildPerlDeps.pm b/traffic_ops/install/lib/BuildPerlDeps.pm
index 5566b73..2bf5eed 100644
--- a/traffic_ops/install/lib/BuildPerlDeps.pm
+++ b/traffic_ops/install/lib/BuildPerlDeps.pm
@@ -17,6 +17,9 @@ use lib qw(/opt/traffic_ops/install/lib /opt/traffic_ops/lib/perl5 /opt/traffic_
 
 package BuildPerlDeps;
 
+use strict;
+use warnings;
+
 use InstallUtils qw{ :all };
 
 use base qw{ Exporter };
@@ -24,7 +27,8 @@ our @EXPORT_OK = qw{ build };
 our %EXPORT_TAGS = ( all => \@EXPORT_OK );
 
 sub build {
-    my $opt_i = shift;
+    my $opt_i       = shift;
+    my $cpanLogFile = shift;
 
     my @dependencies = ( "expat-devel", "mod_ssl", "mkisofs", "libpcap", "libpcap-devel", "libcurl", "libcurl-devel", "mysql-server", "mysql-devel", "openssl", "openssl-devel", "cpan", "gcc", "make", "pkgconfig", "automake", "autoconf", "libtool", "gettext", "libidn-devel" );
 
@@ -46,7 +50,7 @@ EOF
         errorOut("You must run this script as the root user");
     }
 
-    logger( $msg, "info" );
+    InstallUtils::logger( $msg, "info" );
 
     chdir("/opt/traffic_ops/app");
 
@@ -55,43 +59,45 @@ EOF
             errorOut("You must install 'yum'");
         }
 
-        logger( "Installing dependencies", "info" );
-        $result = execCommand( "/usr/bin/yum", "-y", "install", @dependencies );
+        InstallUtils::logger( "Installing dependencies", "info" );
+        $result = InstallUtils::execCommand( "/usr/bin/yum", "-y", "install", @dependencies );
         if ( $result != 0 ) {
             errorOut("Dependency installation failed, look through the output and correct the problem");
         }
-        logger( "Building perl modules", "info" );
+        InstallUtils::logger( "Building perl modules", "info" );
 
-        $result = execCommand( "/usr/bin/cpan", "pi_custom_log=" . $::cpanLogFile, "-if", "YAML" );
+        $result = InstallUtils::execCommand( "/usr/bin/cpan", "pi_custom_log=" . $cpanLogFile, "-if", "YAML" );
         if ( $result != 0 ) {
             errorOut("Failed to install YAML, look through the output and correct the problem");
         }
 
-        $result = execCommand( "/usr/bin/cpan", "pi_custom_log=" . $::cpanLogFile, "-if", "MIYAGAWA/Carton-v1.0.15.tar.gz" );
+        $result = InstallUtils::execCommand( "/usr/bin/cpan", "pi_custom_log=" . $cpanLogFile, "-if", "MIYAGAWA/Carton-v1.0.15.tar.gz" );
         if ( $result != 0 ) {
             errorOut("Failed to install Carton, look through the output and correct the problem");
         }
     }
 
-    $result = execCommand( "/usr/local/bin/carton", "install" );
+    $result = InstallUtils::execCommand( "/usr/local/bin/carton", "install" );
     if ( $result != 0 ) {
         errorOut("Failure to build required perl modules, check the output and correct the problem");
     }
 
     if ( !-s "/opt/traffic_ops/lib/perl5" ) {
-        logger( "Linking perl libraries...", "info" );
+        InstallUtils::logger( "Linking perl libraries...", "info" );
         if ( !-d "/opt/traffic_ops/lib" ) {
             mkdir("/opt/traffic_ops/lib");
         }
         symlink( "/opt/traffic_ops/app/local/lib/perl5", "/opt/traffic_ops/lib/perl5" );
-        execCommand( "/bin/chown", "-R", "trafops:trafops", "/opt/traffic_ops/lib" );
+        InstallUtils::execCommand( "/bin/chown", "-R", "trafops:trafops", "/opt/traffic_ops/lib" );
     }
-    logger( "Installing perl scripts", "info" );
+    InstallUtils::logger( "Installing perl scripts", "info" );
     chdir("/opt/traffic_ops/app/local/bin");
-    my $rc = execCommand( "/bin/cp", "-R", ".", "/opt/traffic_ops/app/bin" );
+    my $rc = InstallUtils::execCommand( "/bin/cp", "-R", ".", "/opt/traffic_ops/app/bin" );
     if ( $rc != 0 ) {
-        logger( "Failed to copy perl scripts to /opt/traffic_ops/app/bin", "error" );
+        InstallUtils::logger( "Failed to copy perl scripts to /opt/traffic_ops/app/bin", "error" );
     }
 
     return 0;
 }
+
+1;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/lib/GenerateCert.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/install/lib/GenerateCert.pm b/traffic_ops/install/lib/GenerateCert.pm
index 8fb1a11..ef2bb46 100644
--- a/traffic_ops/install/lib/GenerateCert.pm
+++ b/traffic_ops/install/lib/GenerateCert.pm
@@ -97,7 +97,7 @@ sub writeCdn_conf {
 # Returns the OpenSSL exit code.
 sub execOpenssl {
     my ( $description, @args ) = @_;
-    logger( $description, "info" );
+    InstallUtils::logger( $description, "info" );
     my $result = 1;
     while ( $result != 0 ) {
         $result = InstallUtils::execCommand( "openssl", @args );
@@ -120,12 +120,12 @@ sub createCert {
     my $opensslconf = shift;
 
     if ( !defined $opensslconf ) {
-        logger( "No input file - running openssl configuration in interactive mode", "info" );
+        InstallUtils::logger( "No input file - running openssl configuration in interactive mode", "info" );
     }
 
-    logger( $msg, "info" );
+    InstallUtils::logger( $msg, "info" );
 
-    logger( "Postinstall SSL Certificate Creation", "info" );
+    InstallUtils::logger( "Postinstall SSL Certificate Creation", "info" );
 
     my $params;
     my $passphrase;
@@ -145,7 +145,7 @@ sub createCert {
     if ( execOpenssl( "Generating an RSA Private Server Key", "genrsa", "-des3", "-out", "server.key", "-passout", "pass:$passphrase", "1024" ) != 0 ) {
         exit 1;
     }
-    logger( "The server key has been generated", "info" );
+    InstallUtils::logger( "The server key has been generated", "info" );
 
     if ($params) {
         if ( execOpenssl( "Creating a Certificate Signing Request (CSR)", "req", "-new", "-key", "server.key", "-out", "server.csr", "-passin", "pass:$passphrase", "-subj", $params ) != 0 ) {
@@ -158,21 +158,21 @@ sub createCert {
         }
     }
 
-    logger( "The Certificate Signing Request has been generated", "info" );
+    InstallUtils::logger( "The Certificate Signing Request has been generated", "info" );
 
     InstallUtils::execCommand( "/bin/mv", "server.key", "server.key.orig" );
 
     if ( execOpenssl( "Removing the pass phrase from the server key", "rsa", "-in", "server.key.orig", "-out", "server.key", "-passin", "pass:$passphrase" ) != 0 ) {
         exit 1;
     }
-    logger( "The pass phrase has been removed from the server key", "info" );
+    InstallUtils::logger( "The pass phrase has been removed from the server key", "info" );
 
     if ( execOpenssl( "Generating a Self-signed certificate", "x509", "-req", "-days", "365", "-in", "server.csr", "-signkey", "server.key", "-out", "server.crt" ) != 0 ) {
         exit 1;
     }
-    logger( "A server key and self signed certificate has been generated", "info" );
+    InstallUtils::logger( "A server key and self signed certificate has been generated", "info" );
 
-    logger( "Installing the server key and server certificate", "info" );
+    InstallUtils::logger( "Installing the server key and server certificate", "info" );
 
     my $result = InstallUtils::execCommand( "/bin/cp", "server.key", "$key" );
     if ( $result != 0 ) {
@@ -185,8 +185,8 @@ sub createCert {
         errorOut("Failed to install the private server key");
     }
 
-    logger( "The private key has been installed",     "info" );
-    logger( "Installing the self signed certificate", "info" );
+    InstallUtils::logger( "The private key has been installed",     "info" );
+    InstallUtils::logger( "Installing the self signed certificate", "info" );
 
     $result = InstallUtils::execCommand( "/bin/cp", "server.crt", "$cert" );
 
@@ -201,7 +201,7 @@ sub createCert {
         errorOut("Failed to install the self signed certificate");
     }
 
-    logger( "Saving the self signed csr", "info" );
+    InstallUtils::logger( "Saving the self signed csr", "info" );
     $result = InstallUtils::execCommand( "/bin/cp", "server.csr", "$csr" );
 
     if ( $result != 0 ) {
@@ -223,7 +223,7 @@ sub createCert {
 
 EOF
 
-    logger( $msg, "info" );
+    InstallUtils::logger( $msg, "info" );
 
     return 0;
 }

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/lib/InstallUtils.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/install/lib/InstallUtils.pm b/traffic_ops/install/lib/InstallUtils.pm
index a4f0266..555ba84 100644
--- a/traffic_ops/install/lib/InstallUtils.pm
+++ b/traffic_ops/install/lib/InstallUtils.pm
@@ -41,6 +41,14 @@ use base qw{ Exporter };
 our @EXPORT_OK = qw{ execCommand randomWord promptUser promptRequired promptPassword promptPasswordVerify trim readJson writeJson writePerl errorOut logger rotateLog};
 our %EXPORT_TAGS = ( all => \@EXPORT_OK );
 
+my $logFile;
+my $debug;
+
+sub initLogger {
+    $debug   = shift;
+    $logFile = shift;
+}
+
 sub execCommand {
     my ( $command, @args ) = @_;
 
@@ -94,7 +102,7 @@ sub rotateLog {
     my $logFileName = shift;
 
     if ( !-f $logFileName ) {
-        logger( "Log file '$logFileName' does not exist - not rotating log", "error" );
+        logger( "Log file '$logFileName' does not exist - not rotating log", "warn" );
         return;
     }
 
@@ -117,7 +125,7 @@ sub logger {
     }
 
     # if in debug mode or message is more critical than info print to console
-    if ( $::debug || ( defined $type && $type ne "" && $type ne "info" ) ) {
+    if ( $debug || ( defined $type && $type ne "" && $type ne "info" ) ) {
         print($message);
     }
 
@@ -125,12 +133,12 @@ sub logger {
     my $fh;
     my $result = 0;
     if ( defined $customLogFile && $customLogFile ne "" ) {
-        open $fh, '>>', $customLogFile or die("Couldn't open log file '$::customLogFile'");
+        open $fh, '>>', $customLogFile or die("Couldn't open log file '$customLogFile'");
         $result = 1;
     }
     else {
-        if ($::logFile) {
-            open $fh, '>>', $::logFile or die("Couldn't open log file '$::logFile'");
+        if ($logFile) {
+            open( $fh, '>>', $logFile ) or die("Couldn't open log file '$logFile'");
             $result = 1;
         }
     }
@@ -233,6 +241,7 @@ sub readJson {
 sub writeJson {
     my $file = shift;
     open( my $fh, '>', $file ) or die("open(): $!");
+    logger("Writing json to $file", "info");
     foreach my $data (@_) {
         my $json_text = JSON->new->utf8->pretty->encode($data);
         print $fh $json_text, "\n";
@@ -251,3 +260,5 @@ sub writePerl {
     print $fh $dumper->Terse(1)->Dump();
     close $fh;
 }
+
+1;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/lib/ProfileCleanup.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/install/lib/ProfileCleanup.pm b/traffic_ops/install/lib/ProfileCleanup.pm
index 3f7ce4a..4885a11 100644
--- a/traffic_ops/install/lib/ProfileCleanup.pm
+++ b/traffic_ops/install/lib/ProfileCleanup.pm
@@ -16,40 +16,46 @@
 
 package ProfileCleanup;
 
+use warnings;
+use strict;
+
 use InstallUtils qw{ :all };
 use WWW::Curl::Easy;
 use LWP::UserAgent;
 
 use base qw{ Exporter };
-our @EXPORT_OK = qw{ replace_profile_templates import_profiles profiles_exist };
+our @EXPORT_OK = qw{ replace_profile_templates import_profiles profiles_exist add_custom_profiles };
 our %EXPORT_TAGS = ( all => \@EXPORT_OK );
 
 sub profile_replace {
-    my ($profile) = @_;
+    my $profile    = shift;
+    my $adminconf  = shift;
+    my $parameters = shift;
+
     my $profile_bak = $profile . ".bak";
-    logger("Replacing parameters in profile: $profile", "info");
+    InstallUtils::logger( "Replacing parameters in profile: $profile", "info" );
     rename( $profile, $profile_bak ) or die("rename(): $!");
     open( my $fh,  '<', $profile_bak ) or die("open(): $!");
     open( my $ofh, '>', $profile )     or die("open(): $!");
     while (<$fh>) {
-        s/{{.TmUrl}}/$::parameters->{'tm.url'}/g;
-        s/{{.TmInfoUrl}}/$::parameters->{"tminfo.url"}/g;
-        s/{{.TmInstanceName}}/$::parameters->{"cdnname"}/g;
-        s/{{.GeolocationPollingUrl}}/$::parameters->{"geolocation.polling.url"}/g;
-        s/{{.Geolocation6PollingUrl}}/$::parameters->{"geolocation6.polling.url"}/g;
-        s/{{.TmUrl}}/$::parameters->{'tm.url'}/g;
+        s/{{.TmUrl}}/$parameters->{'tm.url'}/g;
+        s/{{.TmInfoUrl}}/$parameters->{"tminfo.url"}/g;
+        s/{{.TmInstanceName}}/$parameters->{"cdnname"}/g;
+        s/{{.GeolocationPollingUrl}}/$parameters->{"geolocation.polling.url"}/g;
+        s/{{.Geolocation6PollingUrl}}/$parameters->{"geolocation6.polling.url"}/g;
+        s/{{.TmUrl}}/$parameters->{'tm.url'}/g;
         s/{{.TmToolName}}/Traffic Ops/g;
-        s/{{.HealthPollingInterval}}/$::parameters->{"health.polling.interval"}/g;
-        s/{{.CoveragezonePollingUrl}}/$::parameters->{"coveragezone.polling.url"}/g;
-        s/{{.DomainName}}/$::parameters->{"domainname"}/g;
-        s/{{.TldSoaAdmin}}/$::parameters->{"tld.soa.admin"}/g;
-        s/{{.DrivePrefix}}/$::parameters->{"Drive_Prefix"}/g;
-        s/{{.HealthThresholdLoadavg}}/$::parameters->{"health.threshold.loadavg"}/g;
-        s/{{.HealthThresholdAvailableBandwidthInKbps}}/$::parameters->{"health.threshold.availableBandwidthInKbps"}/g;
-        s/{{.RAMDrivePrefix}}/$::parameters->{"RAM_Drive_Prefix"}/g;
-        s/{{.RAMDriveLetters}}/$::parameters->{"RAM_Drive_Letters"}/g;
-        s/{{.HealthConnectionTimeout}}/$::parameters->{"health.connection.timeout"}/g;
-        s#{{.CronOrtSyncds}}#*/15 * * * * root /opt/ort/traffic_ops_ort.pl syncds warn $::parameters->{'tm.url'} $tmAdminUser:$tmAdminPw > /tmp/ort/syncds.log 2>&1#g;
+        s/{{.HealthPollingInterval}}/$parameters->{"health.polling.interval"}/g;
+        s/{{.CoveragezonePollingUrl}}/$parameters->{"coveragezone.polling.url"}/g;
+        s/{{.DomainName}}/$parameters->{"domainname"}/g;
+        s/{{.TldSoaAdmin}}/$parameters->{"tld.soa.admin"}/g;
+        s/{{.DrivePrefix}}/$parameters->{"Drive_Prefix"}/g;
+        s/{{.HealthThresholdLoadavg}}/$parameters->{"health.threshold.loadavg"}/g;
+        s/{{.HealthThresholdAvailableBandwidthInKbps}}/$parameters->{"health.threshold.availableBandwidthInKbps"}/g;
+        s/{{.RAMDrivePrefix}}/$parameters->{"RAM_Drive_Prefix"}/g;
+        s/{{.RAMDriveLetters}}/$parameters->{"RAM_Drive_Letters"}/g;
+        s/{{.HealthConnectionTimeout}}/$parameters->{"health.connection.timeout"}/g;
+        s#{{.CronOrtSyncds}}#*/15 * * * * root /opt/ort/traffic_ops_ort.pl syncds warn $parameters->{'tm.url'} $adminconf->{tmAdminUser}:$adminconf->{tmAdminPw} > /tmp/ort/syncds.log 2>&1#g;
         print $ofh $_;
     }
     close $fh;
@@ -58,30 +64,34 @@ sub profile_replace {
 }
 
 sub replace_profile_templates {
-    my $conf = shift;
-
-    $::parameters->{'tm.url'}                                    = $conf->{"tm.url"};
-    $::parameters->{"tminfo.url"}                                = "$::parameters->{'tm.url'}/info";
-    $::parameters->{"cdnname"}                                   = $conf->{"cdn_name"};
-    $::parameters->{"geolocation.polling.url"}                   = "$::parameters->{'tm.url'}/routing/GeoIP2-City.mmdb.gz";
-    $::parameters->{"geolocation6.polling.url"}                  = "$::parameters->{'tm.url'}/routing/GeoIP2-Cityv6.mmdb.gz";
-    $::parameters->{"health.polling.interval"}                   = $conf->{"health_polling_int"};
-    $::parameters->{"coveragezone.polling.url"}                  = "$::parameters->{'tm.url'}/routing/coverage-zone.json";
-    $::parameters->{"domainname"}                                = $conf->{"dns_subdomain"};
-    $::parameters->{"tld.soa.admin"}                             = $conf->{"soa_admin"};
-    $::parameters->{"Drive_Prefix"}                              = $conf->{"driver_prefix"};
-    $::parameters->{"RAM_Drive_Prefix"}                          = $conf->{"ram_drive_prefix"};
-    $::parameters->{"RAM_Drive_Letters"}                         = $conf->{"ram_drive_letters"};
-    $::parameters->{"health.threshold.loadavg"}                  = $conf->{"health_thresh_load_avg"};
-    $::parameters->{"health.threshold.availableBandwidthInKbps"} = $conf->{"health_thresh_kbps"};
-    $::parameters->{"health.connection.timeout"}                 = $conf->{"health_connect_timeout"};
-
-    profile_replace( $::profile_dir . "profile.global.traffic_ops" );
-    profile_replace( $::profile_dir . "profile.traffic_monitor.traffic_ops" );
-    profile_replace( $::profile_dir . "profile.traffic_router.traffic_ops" );
-    profile_replace( $::profile_dir . "profile.trafficserver_edge.traffic_ops" );
-    profile_replace( $::profile_dir . "profile.trafficserver_mid.traffic_ops" );
-    writeJson( $::post_install_cfg, $::parameters );
+    my $conf             = shift;
+    my $adminconf        = shift;
+    my $post_install_cfg = shift;
+    my $parameters       = shift;
+    my $profileDir       = shift;
+
+    $parameters->{'tm.url'}                                    = $conf->{"tm.url"};
+    $parameters->{"tminfo.url"}                                = "$parameters->{'tm.url'}/info";
+    $parameters->{"cdnname"}                                   = $conf->{"cdn_name"};
+    $parameters->{"geolocation.polling.url"}                   = "$parameters->{'tm.url'}/routing/GeoIP2-City.mmdb.gz";
+    $parameters->{"geolocation6.polling.url"}                  = "$parameters->{'tm.url'}/routing/GeoIP2-Cityv6.mmdb.gz";
+    $parameters->{"health.polling.interval"}                   = $conf->{"health_polling_int"};
+    $parameters->{"coveragezone.polling.url"}                  = "$parameters->{'tm.url'}/routing/coverage-zone.json";
+    $parameters->{"domainname"}                                = $conf->{"dns_subdomain"};
+    $parameters->{"tld.soa.admin"}                             = $conf->{"soa_admin"};
+    $parameters->{"Drive_Prefix"}                              = $conf->{"driver_prefix"};
+    $parameters->{"RAM_Drive_Prefix"}                          = $conf->{"ram_drive_prefix"};
+    $parameters->{"RAM_Drive_Letters"}                         = $conf->{"ram_drive_letters"};
+    $parameters->{"health.threshold.loadavg"}                  = $conf->{"health_thresh_load_avg"};
+    $parameters->{"health.threshold.availableBandwidthInKbps"} = substr( $conf->{"health_thresh_kbps"}, 0, 1 ) eq ">" ? "" : ">" . $conf->{"health_thresh_kbps"};
+    $parameters->{"health.connection.timeout"}                 = $conf->{"health_connect_timeout"};
+
+    profile_replace( $profileDir . "profile.global.traffic_ops",             $adminconf, $parameters );
+    profile_replace( $profileDir . "profile.traffic_monitor.traffic_ops",    $adminconf, $parameters );
+    profile_replace( $profileDir . "profile.traffic_router.traffic_ops",     $adminconf, $parameters );
+    profile_replace( $profileDir . "profile.trafficserver_edge.traffic_ops", $adminconf, $parameters );
+    profile_replace( $profileDir . "profile.trafficserver_mid.traffic_ops",  $adminconf, $parameters );
+    writeJson( $post_install_cfg, $parameters );
 }
 
 # Takes the Traffic Ops URI, user, and password.
@@ -117,54 +127,59 @@ sub get_traffic_ops_cookie {
 # Takes the filename of a Traffic Ops (TO) profile to import, the TO URI, and the TO login cookie
 sub profile_import_single {
     my ( $profileFilename, $uri, $trafficOpsCookie ) = @_;
-    logger( "Importing Profiles with: " . "curl -v -k -X POST -H \"Cookie: mojolicious=$trafficOpsCookie\" -F \"filename=$profileFilename\" -F \"profile_to_import=\@$profileFilename\" $uri/profile/doImport", "info" );
-    my $rc = execCommand("curl -v -k -X POST -H \"Cookie: mojolicious=$trafficOpsCookie\" -F \"filename=$profileFilename\" -F \"profile_to_import=\@$profileFilename\" $uri/profile/doImport");
+    InstallUtils::logger( "Importing Profiles with: " . "curl -v -k -X POST -H \"Cookie: mojolicious=$trafficOpsCookie\" -F \"filename=$profileFilename\" -F \"profile_to_import=\@$profileFilename\" $uri/profile/doImport", "info" );
+    my $rc = InstallUtils::execCommand("curl -v -k -X POST -H \"Cookie: mojolicious=$trafficOpsCookie\" -F \"filename=$profileFilename\" -F \"profile_to_import=\@$profileFilename\" $uri/profile/doImport");
     if ( $rc != 0 ) {
-        logger( "Failed to import Traffic Ops profile, check the console output and rerun postinstall once you've resolved the error", "error" );
+        InstallUtils::logger( "Failed to import Traffic Ops profile, check the console output and rerun postinstall once you've resolved the error", "error" );
     }
 }
 
 sub import_profiles {
-    my $config = shift;
-    logger( "Importing profiles...", "info" );
+    my $toUri = shift;
+    my $adminconf  = shift;
+    my $profileDir = shift;
 
-    my $toUri  = $::parameters->{'tm.url'};
-    my $toUser = $config->{"username"};
-    my $toPass = $config->{"password"};
+    InstallUtils::logger( "Importing profiles...", "info" );
+
+    my $toUser = $adminconf->{"username"};
+    my $toPass = $adminconf->{"password"};
 
     my $toCookie = get_traffic_ops_cookie( $toUri, $toUser, $toPass );
 
-    logger( "Got cookie: " . $toCookie, "info" );
+    InstallUtils::logger( "Got cookie: " . $toCookie, "info" );
 
     # \todo use an array?
-    logger( "Importing Global profile...", "info" );
-    profile_import_single( $::profile_dir . "profile.global.traffic_ops", $toUri, $toCookie );
-    logger( "Importing Traffic Monitor profile...", "info" );
-    profile_import_single( $::profile_dir . "profile.traffic_monitor.traffic_ops", $toUri, $toCookie );
-    logger( "Importing Traffic Router profile...", "info" );
-    profile_import_single( $::profile_dir . "profile.traffic_router.traffic_ops", $toUri, $toCookie );
-    logger( "Importing TrafficServer Edge profile...", "info" );
-    profile_import_single( $::profile_dir . "profile.trafficserver_edge.traffic_ops", $toUri, $toCookie );
-    logger( "Importing TrafficServer Mid profile...", "info" );
-    profile_import_single( $::profile_dir . "profile.trafficserver_mid.traffic_ops", $toUri, $toCookie );
-    logger( "Finished Importing Profiles.", "info" );
+    InstallUtils::logger( "Importing Global profile...", "info" );
+    profile_import_single( $profileDir . "profile.global.traffic_ops", $toUri, $toCookie );
+    InstallUtils::logger( "Importing Traffic Monitor profile...", "info" );
+    profile_import_single( $profileDir . "profile.traffic_monitor.traffic_ops", $toUri, $toCookie );
+    InstallUtils::logger( "Importing Traffic Router profile...", "info" );
+    profile_import_single( $profileDir . "profile.traffic_router.traffic_ops", $toUri, $toCookie );
+    InstallUtils::logger( "Importing TrafficServer Edge profile...", "info" );
+    profile_import_single( $profileDir . "profile.trafficserver_edge.traffic_ops", $toUri, $toCookie );
+    InstallUtils::logger( "Importing TrafficServer Mid profile...", "info" );
+    profile_import_single( $profileDir . "profile.trafficserver_mid.traffic_ops", $toUri, $toCookie );
+    InstallUtils::logger( "Finished Importing Profiles.", "info" );
 }
 
 sub profiles_exist {
-    my $config = shift;
-    my $tmurl  = shift;
-
-    if ( -f $::reconfigure_defaults ) {
-        logger( "Default profiles were previously created. Remove " . $::reconfigure_defaults . " to create again", "warn" );
+    my $config               = shift;
+    my $tmurl                = shift;
+    my $parameters           = shift;
+    my $reconfigure_defaults = shift;
+    my $reconfigure          = shift;
+
+    if ( -f $reconfigure_defaults ) {
+        InstallUtils::logger( "Default profiles were previously created. Remove " . $reconfigure_defaults . " to create again", "warn" );
         return 1;
     }
 
-    $::parameters->{'tm.url'} = $tmurl;
+    $parameters->{'tm.url'} = $tmurl;
 
-    logger( "Checking profiles at $tmurl using username " . $config->{"username"}, "info" );
+    InstallUtils::logger( "Checking profiles at $tmurl using username " . $config->{"username"}, "info" );
 
-    my $uri = $::parameters->{'tm.url'};
-    my $toCookie = get_traffic_ops_cookie( $::parameters->{'tm.url'}, $config->{"username"}, $config->{"password"} );
+    my $uri = $parameters->{'tm.url'};
+    my $toCookie = get_traffic_ops_cookie( $parameters->{'tm.url'}, $config->{"username"}, $config->{"password"} );
 
     my $profileEndpoint = "/api/1.2/profiles.json";
 
@@ -175,7 +190,7 @@ sub profiles_exist {
     my $resp = $ua->request($req);
 
     if ( !$resp->is_success ) {
-        logger( "Error checking if profiles exist: " . $resp->status_line, "error" );
+        InstallUtils::logger( "Error checking if profiles exist: " . $resp->status_line, "error" );
         return 1;    # return true, so we don't attempt to create profiles
     }
     my $message = $resp->decoded_content;
@@ -184,12 +199,12 @@ sub profiles_exist {
     if (   ( !defined $profiles->{"response"} )
         || ( ref $profiles->{"response"} ne 'ARRAY' ) )
     {
-        logger( "Error checking if profiles exist: invalid JSON: $message", "error" );
+        InstallUtils::logger( "Error checking if profiles exist: invalid JSON: $message", "error" );
         return 1;    # return true, so we don't attempt to create profiles
     }
 
     my $num_profiles = scalar( @{ $profiles->{"response"} } );
-    logger( "Existing Profile Count: $num_profiles", "info" );
+    InstallUtils::logger( "Existing Profile Count: $num_profiles", "info" );
 
     my %initial_profiles = (
         "INFLUXDB"      => 1,
@@ -200,11 +215,37 @@ sub profiles_exist {
     my $profiles_response = $profiles->{"response"};
     foreach my $profile (@$profiles_response) {
         if ( !exists $initial_profiles{ $profile->{"name"} } ) {
-            logger( "Found existing profile (" . $profile->{"name"} . ")", "info" );
-            open( my $reconfigure_defaults_file, '>', $::reconfigure_defaults ) or die("Failed to open() $reconfigure_defaults: $!");
-            close($reconfigure_defaults_file);
+            InstallUtils::logger( "Found existing profile (" . $profile->{"name"} . ")", "info" );
+            open( my $reconfigure_defaults, '>', $reconfigure ) or die("Failed to open() $reconfigure_defaults: $!");
+            close($reconfigure_defaults);
             return 1;
         }
     }
     return 0;
 }
+
+sub add_custom_profiles {
+    my $custom_profile_dir = shift;
+    my $adminconf = shift;
+    my $toUri = shift;
+
+    return if (! -e $custom_profile_dir );
+
+    opendir(DH, $custom_profile_dir) || return;
+    my @profiles = readdir(DH);
+    closedir(DH);
+    @profiles = grep(/^profile\..*\.traffic_ops$/, @profiles);
+
+    return if (scalar @profiles == 0);
+
+    my $toUser = $adminconf->{tmAdminUser};
+    my $toPass = $adminconf->{tmAdminPw};
+    my $toCookie = get_traffic_ops_cookie($toUri, $toUser, $toPass);
+
+    foreach my $profile (@profiles) {
+        print "\nimport profile ". $custom_profile_dir . $profile . "\n\n";
+        profile_import_single($custom_profile_dir . $profile, $toUri, $toCookie);
+    }
+}
+
+1;

http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/230aa7c0/traffic_ops/install/lib/WebDep.pm
----------------------------------------------------------------------
diff --git a/traffic_ops/install/lib/WebDep.pm b/traffic_ops/install/lib/WebDep.pm
index e7db9b6..edf25fb 100644
--- a/traffic_ops/install/lib/WebDep.pm
+++ b/traffic_ops/install/lib/WebDep.pm
@@ -1,6 +1,7 @@
 package WebDep;
 
 #
+# Copyright 2015 Comcast Cable Communications Management, LLC
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -30,205 +31,205 @@ my @columns = qw{name version cdn_location compression filename source_dir final
 
 # class method returns list of WebDep objects loaded from file
 sub getDeps {
-	my $class = shift;
-
-	my $webdeps_file = shift;
-	my @deps;
-	open my $fh, '<', $webdeps_file or die "Can't open $webdeps_file\n";
-
-	# final_dir within webdeps_file are absolute or relative to directory that file is in
-	my $oldcwd      = getcwd();
-	my $webdeps_dir = dirname($webdeps_file);
-	chdir($webdeps_dir);
-	while (<$fh>) {
-
-		# comments only if line starts with #
-		next if /^#/;
-		chomp;
-		my @parts = split( /\s*,\s*/, $_ );
-		my $obj = bless {}, $class;
-		for my $attrib (@columns) {
-			$obj->{$attrib} = shift @parts;
-		}
-		$obj->{filename} =~ s{^/}{};
-		$obj->{source_dir} =~ s{/$}{};
-		$obj->{source_dir} =~ s{/$}{};
-
-		my $final_dir = $obj->{final_dir};
-		if ( !-d $final_dir ) {
-			print "Making dir: $final_dir\n";
-			mkpath($final_dir);
-		}
-		$obj->{final_dir} = abs_path($final_dir);
-		push( @deps, $obj );
-	}
-	chdir($oldcwd);
-	return @deps;
+    my $class = shift;
+
+    my $webdeps_file = shift;
+    my @deps;
+    open my $fh, '<', $webdeps_file or die "Can't open $webdeps_file\n";
+
+    # final_dir within webdeps_file are absolute or relative to directory that file is in
+    my $oldcwd      = getcwd();
+    my $webdeps_dir = dirname($webdeps_file);
+    chdir($webdeps_dir);
+    while (<$fh>) {
+
+        # comments only if line starts with #
+        next if /^#/;
+        chomp;
+        my @parts = split( /\s*,\s*/, $_ );
+        my $obj = bless {}, $class;
+        for my $attrib (@columns) {
+            $obj->{$attrib} = shift @parts;
+        }
+        $obj->{filename} =~ s{^/}{};
+        $obj->{source_dir} =~ s{/$}{};
+        $obj->{source_dir} =~ s{/$}{};
+
+        my $final_dir = $obj->{final_dir};
+        if ( !-d $final_dir ) {
+            print "Making dir: $final_dir\n";
+            mkpath($final_dir);
+        }
+        $obj->{final_dir} = abs_path($final_dir);
+        push( @deps, $obj );
+    }
+    chdir($oldcwd);
+    return @deps;
 }
 
 sub getSrcFileName {
-	my $self = shift;
-	my @parts;
-	push @parts, $self->{source_dir} if $self->{source_dir} ne '';
-	push @parts, $self->{filename};
-	return join( '/', @parts );
+    my $self = shift;
+    my @parts;
+    push @parts, $self->{source_dir} if $self->{source_dir} ne '';
+    push @parts, $self->{filename};
+    return join( '/', @parts );
 }
 
 sub getDestFileName {
-	my $self = shift;
-	return join( '/', $self->{final_dir}, $self->{filename} );
+    my $self = shift;
+    return join( '/', $self->{final_dir}, $self->{filename} );
 }
 
 sub getDownloadContent {
-	my $self = shift;
-	my ( $response_body, $err ) = _getDownloadContent( $self->{cdn_location} );
-	return ( $response_body, $err );
+    my $self = shift;
+    my ( $response_body, $err ) = _getDownloadContent( $self->{cdn_location} );
+    return ( $response_body, $err );
 }
 
 sub getContent {
-	my $self = shift;
-	my ( $content, $err ) = $self->getDownloadContent();
-	if ( defined $err ) {
-		die "$err\n";
-	}
-	my $srcfn = $self->getSrcFileName();
-	if ( !exists $self->{content} ) {
-		if ( $self->{compression} eq 'zip' ) {
-
-			#print "Unzipping $srcfn\n";
-			my $u = IO::Uncompress::Unzip->new( \$content ) or die "IO::Uncompress::Unzip failed: $UnzipError\n";
-			my $found;
-			while ( $u->nextStream() > 0 && !$u->eof() ) {
-				my $name = $u->getHeaderInfo()->{Name};
-				if ( $name eq $srcfn ) {
-					$found = $name;
-					last;
-				}
-			}
-			if ( !defined $found ) {
-				die "$srcfn not found in " . $self->{cdn_location} . "\n";
-			}
-
-			undef $/;    # slurp mode
-			$content = <$u>;
-			$u->close();
-		}
-
-		$self->{content} = $content;
-	}
-	return $self->{content};
+    my $self = shift;
+    my ( $content, $err ) = $self->getDownloadContent();
+    if ( defined $err ) {
+        die "$err\n";
+    }
+    my $srcfn = $self->getSrcFileName();
+    if ( !exists $self->{content} ) {
+        if ( $self->{compression} eq 'zip' ) {
+
+            #print "Unzipping $srcfn\n";
+            my $u = IO::Uncompress::Unzip->new( \$content ) or die "IO::Uncompress::Unzip failed: $UnzipError\n";
+            my $found;
+            while ( $u->nextStream() > 0 && !$u->eof() ) {
+                my $name = $u->getHeaderInfo()->{Name};
+                if ( $name eq $srcfn ) {
+                    $found = $name;
+                    last;
+                }
+            }
+            if ( !defined $found ) {
+                die "$srcfn not found in " . $self->{cdn_location} . "\n";
+            }
+
+            undef $/;    # slurp mode
+            $content = <$u>;
+            $u->close();
+        }
+
+        $self->{content} = $content;
+    }
+    return $self->{content};
 }
 
 sub needsUpdating {
-	my $self = shift;
-	my $fn   = $self->getDestFileName();
+    my $self = shift;
+    my $fn   = $self->getDestFileName();
 
-	# checksum and compare
-	open my $fh, '<', $fn or die "Can't open existing file: $fn\n";
-	my $md5_existing = md5_hex(<$fh>);
-	close $fh;
+    # checksum and compare
+    open my $fh, '<', $fn or die "Can't open existing file: $fn\n";
+    my $md5_existing = md5_hex(<$fh>);
+    close $fh;
 
-	my $md5_new       = md5_hex( $self->getContent() );
-	my $needsUpdating = ( $md5_new ne $md5_existing );
-	return $needsUpdating;
+    my $md5_new       = md5_hex( $self->getContent() );
+    my $needsUpdating = ( $md5_new ne $md5_existing );
+    return $needsUpdating;
 }
 
 sub update {
-	my $self = shift;
-	my $err;
-	my $srcfn  = $self->getSrcFileName();
-	my $destfn = $self->getDestFileName();
-	my $action = "";
-
-	# download archive
-	if ( -f $destfn ) {
-		if ( !$self->needsUpdating() ) {
-			$action = "Kept";
-			return ( $action, $err );
-		}
-
-		# exists but needs to be replaced
-		$action = "Replaced";
-	}
-	else {
-		$action = "Created";
-	}
-	my $content = $self->getContent();
-	open my $ofh, '>', $destfn or $err = "Can't write to $destfn";
-	if ( !defined $err ) {
-		print $ofh $content;
-		close $ofh;
-	}
-	return ( $action, $err );
+    my $self = shift;
+    my $err;
+    my $srcfn  = $self->getSrcFileName();
+    my $destfn = $self->getDestFileName();
+    my $action = "";
+
+    # download archive
+    if ( -f $destfn ) {
+        if ( !$self->needsUpdating() ) {
+            $action = "Kept";
+            return ( $action, $err );
+        }
+
+        # exists but needs to be replaced
+        $action = "Replaced";
+    }
+    else {
+        $action = "Created";
+    }
+    my $content = $self->getContent();
+    open my $ofh, '>', $destfn or $err = "Can't write to $destfn";
+    if ( !defined $err ) {
+        print $ofh $content;
+        close $ofh;
+    }
+    return ( $action, $err );
 }
 
 ####################################################################
 # Utilities
 sub execCommand {
-	my ( $command, @args ) = @_;
-	my $pid    = fork();
-	my $result = 0;
-
-	if ( $pid == 0 ) {
-		exec( $command, @args );
-		exit 0;
-	}
-	else {
-		wait;
-		$result = $?;
-		if ( $result != 0 ) {
-			print "ERROR executing: $command,  args: " . join( ' ', @args ) . "\n";
-		}
-	}
-	return $result;
+    my ( $command, @args ) = @_;
+    my $pid    = fork();
+    my $result = 0;
+
+    if ( $pid == 0 ) {
+        exec( $command, @args );
+        exit 0;
+    }
+    else {
+        wait;
+        $result = $?;
+        if ( $result != 0 ) {
+            print "ERROR executing: $command,  args: " . join( ' ', @args ) . "\n";
+        }
+    }
+    return $result;
 }
 
 sub curlMe {
-	my $url  = shift;
-	my $curl = WWW::Curl::Easy->new;
-	my $response_body;
-	my $err;    # undef if no error
-
-	$curl->setopt( CURLOPT_VERBOSE, 0 );
-	if ( $url =~ m/https/ ) {
-		$curl->setopt( CURLOPT_SSL_VERIFYHOST, 0 );
-		$curl->setopt( CURLOPT_SSL_VERIFYPEER, 0 );
-	}
-	$curl->setopt( CURLOPT_IPRESOLVE,      1 );
-	$curl->setopt( CURLOPT_FOLLOWLOCATION, 1 );
-	$curl->setopt( CURLOPT_CONNECTTIMEOUT, 5 );
-	$curl->setopt( CURLOPT_TIMEOUT,        15 );
-	$curl->setopt( CURLOPT_HEADER,         0 );
-	$curl->setopt( CURLOPT_URL,            $url );
-	$curl->setopt( CURLOPT_WRITEDATA,      \$response_body );
-	my $retcode       = $curl->perform;
-	my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
-
-	if ( $response_code != 200 ) {
-		$err = "Got HTTP $response_code response for '$url'";
-	}
-	elsif ( length($response_body) == 0 ) {
-		$err = "URL: $url returned empty!!";
-	}
-	return ( $response_body, $err );
+    my $url  = shift;
+    my $curl = WWW::Curl::Easy->new;
+    my $response_body;
+    my $err;    # undef if no error
+
+    $curl->setopt( CURLOPT_VERBOSE, 0 );
+    if ( $url =~ m/https/ ) {
+        $curl->setopt( CURLOPT_SSL_VERIFYHOST, 0 );
+        $curl->setopt( CURLOPT_SSL_VERIFYPEER, 0 );
+    }
+    $curl->setopt( CURLOPT_IPRESOLVE,      1 );
+    $curl->setopt( CURLOPT_FOLLOWLOCATION, 1 );
+    $curl->setopt( CURLOPT_CONNECTTIMEOUT, 5 );
+    $curl->setopt( CURLOPT_TIMEOUT,        15 );
+    $curl->setopt( CURLOPT_HEADER,         0 );
+    $curl->setopt( CURLOPT_URL,            $url );
+    $curl->setopt( CURLOPT_WRITEDATA,      \$response_body );
+    my $retcode       = $curl->perform;
+    my $response_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+
+    if ( $response_code != 200 ) {
+        $err = "Got HTTP $response_code response for '$url'";
+    }
+    elsif ( length($response_body) == 0 ) {
+        $err = "URL: $url returned empty!!";
+    }
+    return ( $response_body, $err );
 }
 
 {
-	# cache cdn locs -- some files extracted from same downloaded archive
-	my %content_for;
-
-	sub _getDownloadContent {
-		my $cdnloc = shift;
-		my $err;
-		if ( !exists $content_for{$cdnloc} ) {
-			my $response_body;
-			( $response_body, $err ) = curlMe($cdnloc);
-			$content_for{$cdnloc} = $response_body;
-		}
-
-		# could be undef indicating previous error
-		return ( $content_for{$cdnloc}, $err );
-	}
+    # cache cdn locs -- some files extracted from same downloaded archive
+    my %content_for;
+
+    sub _getDownloadContent {
+        my $cdnloc = shift;
+        my $err;
+        if ( !exists $content_for{$cdnloc} ) {
+            my $response_body;
+            ( $response_body, $err ) = curlMe($cdnloc);
+            $content_for{$cdnloc} = $response_body;
+        }
+
+        # could be undef indicating previous error
+        return ( $content_for{$cdnloc}, $err );
+    }
 }
 
 1;