The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl
# make_sandbox_from_installed
#    The MySQL Sandbox
#    Copyright (C) 2006-2016 Giuseppe Maxia
#
#    Licensed 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.

use strict;
use warnings;
use MySQL::Sandbox qw(runs_as_root);

runs_as_root();

my $new_version = shift
    or die "version needed\n";
if ($new_version =~ /^(-h|--help)$/) {
    print MySQL::Sandbox::credits();
    print<<END_HELP;

This script tries to create a sandbox using already installed binaries.
Since these binaries can be in several different places, the script 
creates a container with symbolic links, where the binaries 
(their links, actually) are arranged as MySQL Sandbox expects them to be.

To use this version, change directory to a place where you want to 
store this symbolic links container, and invoke

  make_sandbox_from_installed X.X.XX [options]

    where X.X.XX is the version number. 
    You can then pass any options accepted by make_sandbox.
END_HELP

    exit(1);

}

$new_version =~ /^\d+\.\d+\.\d+$/ 
    or die "invalid version format (required #.#.##)\n";

my $current_dir = $ENV{PWD};

if ( -d $new_version) {
    die "directory $new_version already exists. Choose another name or location\n"
}

my @binaries = (
    {files => 'my*',                from => 'bin/',     to => 'bin'},
    {files => 'resolveip',          from => 'bin/',     to => 'bin'},
    {files => 'mysql_install_db',   from => 'scripts/', to => 'bin', optional => 1},
    {files => 'mysql*',             from => 'lib64/',   to => 'lib', optional => 1},
    {files => 'mysql*',             from => 'lib/',     to => 'lib', optional => 1},
    {files => 'mysql*',             from => 'libexec/', to => 'bin', optional =>1},
    {files => 'mysql*',             from => 'sbin/',    to => 'bin', optional =>1},
    {files => 'mysql/',             from => 'share/',   to => 'share', optional =>1},
);

my @commands;
my @prefixes = (
    '/usr',
    '/usr/local',
    '/usr/local/mysql',
);

my $found_mysqld        = 0;
my $found_install_db    = 0;
my $found_libraries     = 0;

for my $prefix (@prefixes) {
    if (
       (-x "$prefix/bin/mysqld") 
       or (-x "$prefix/libexec/mysqld")
       or (-x "$prefix/sbin/mysqld")
       ) 
    {
        $found_mysqld =1;
    }
    if (
        (-x "$prefix/bin/mysql_install_db") 
        or (-x "$prefix/scripts/mysql_install_db")
        ) 
    {
        $found_install_db =1;
    }
    if ( glob("$prefix/lib/mysql/libmysqlclient*") 
       or glob( "$prefix/lib/libmysqlclient*")
       or glob( "$prefix/lib64/libmysqlclient*")  ) {
        $found_libraries =1;
    }
}

unless ($found_mysqld) {
    die "can't find mysqld in (@prefixes)\n";
}
unless ($found_install_db) {
    die "can't find mysql_install_db in (@prefixes)\n";
}
unless ($found_libraries) {
    die "can't find mysql libraries in (@prefixes)\n";
}

for my $bin ( @binaries ) {
    my $found_prefix = undef;
    for my $prefix (@prefixes) {
        if ($bin->{files} =~ /\*/ ) {
            my @files = glob("$prefix/$bin->{from}/$bin->{files}");
            if (@files) {
                $found_prefix = $prefix;
                last;
            }
        }
        else {
            if ( -e "$prefix/$bin->{from}/$bin->{files}") {
                $found_prefix = $prefix;
                last;
            }
        }
    }
    unless ( $found_prefix) {
        if ($bin->{optional}) {
            next;
        }
        die "can't find $bin->{from}/$bin->{files} under (@prefixes) \n";
    }
    push @commands, sprintf("ln -s %s/%s/%s %s/%s/%s",
        $found_prefix,
        $bin->{from},
        $bin->{files},
        $current_dir,
        $new_version,
        $bin->{to}
    );
}

unless (grep { /share/ } @commands) {
    if ( -d "/usr/local/mysql/share" ) {
        push @commands, "ln -s /usr/local/mysql/share/* $current_dir/$new_version/share";
    }
}

#use Data::Dumper;
#print Dumper \@commands; 
#exit;
mkdir $new_version 
    or die "can't create $new_version ($!)\n";

chdir $new_version;
for my $dir (qw(bin lib share)) {
    mkdir $dir
        or die "can't create $new_version/$dir\n";
}

for my $command (@commands) {
    system $command;
    if ($?) {
        die "error creating symbolic link ($command) \n";
    } 
}

$ENV{SANDBOX_BINARY} = $current_dir;
system "make_sandbox $new_version -- @ARGV";