GeoHelm/postgis/setup.cgi

491 lines
16 KiB
Perl

#!/usr/bin/perl
require './geohelm-lib.pl';
require './pg-lib.pl';
require '../webmin/webmin-lib.pl'; #for OS detection
foreign_require('apache', 'apache-lib.pl');
foreign_require('software', 'software-lib.pl');
$crunchy_user = 'pgis';
$crunchy_db = 'postgisftw';
$db_pass = '';
$www_user = 'www-data';
sub get_http_conf_path{
my $filename = $_[0];
my $filepath = '';
my $avail = $_[1];
if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora
($osinfo{'real_os_type'} =~ /scientific/i) ){
$filepath = '/etc/httpd/conf.d/'.$filename;
}elsif( ($osinfo{'real_os_type'} =~ /ubuntu/i) or
($osinfo{'real_os_type'} =~ /debian/i) ){ #ubuntu or debian
if($avail){
$filepath = '/etc/apache2/conf-available/'.$filename;
}else{
$filepath = '/etc/apache2/conf-enabled/'.$filename;
}
}
return $filepath;
}
sub latest_leafletjs_version(){
my $tmpfile = download_file('https://leafletjs.com/download.html');
my $latest_url = 'https://leafletjs-cdn.s3.amazonaws.com/content/leaflet/v1.9.3/leaflet.zip';
open(my $fh, '<', $tmpfile) or die "open:$!";
while(my $line = <$fh>){
if($line =~ /(https:\/\/.*leaflet\/v[0-9\.]+\/leaflet\.zip)/){
$latest_ver = $1;
last;
}
}
close $fh;
return $latest_url;
}
sub install_leafletjs{
if( -d '/var/www/html/leafletjs'){
return 0;
}
my $ll_url = latest_leafletjs_version();
my $tmpfile = download_file($ll_url);
my $ll_dir = unzip_me($tmpfile);
print "Moving to /var/www/html/leafletjs ...";
rename_file($ll_dir, '/var/www/html/leafletjs');
exec_cmd("chown -R $www_user:$www_user '/var/www/html/leafletjs'");
}
sub latest_openlayers_version(){
my $tmpfile = download_file('https://openlayers.org/download');
my $latest_ver = '0.0.0';
open(my $fh, '<', $tmpfile) or die "open:$!";
while(my $line = <$fh>){
#Downloads for the v4.2.0 release
if($line =~ /Downloads\sfor\sthe\sv([0-9\.]+)\srelease/){
$latest_ver = $1;
last;
}
}
close $fh;
return $latest_ver;
}
sub install_openlayers{
if( -d '/var/www/html/OpenLayers'){
return 0;
}
#get OpenLayers version
my $ol_ver = latest_openlayers_version();
my $dist = '-package'; #'-site' string for full release or '-package' for libs only
my $tmpfile = download_file("https://github.com/openlayers/openlayers/releases/download/v${ol_ver}/v${ol_ver}${dist}.zip");
if(!$tmpfile){
die "Error: Failed to get latest OpenLayers archive";
}
my $ol_dir = unzip_me($tmpfile);
print "Moving ${ol_dir} to /var/www/html/OpenLayers ...";
rename_file($ol_dir, '/var/www/html/OpenLayers');
&exec_cmd("chown -R $www_user:$www_user '/var/www/html/OpenLayers'");
}
sub install_bootstrap_web_app(){
my $www_dir = '/var/www/html';
if( ! -d $www_dir){
print &html_escape("Error: $www_dir is missing");
return 0;
}
#download bootstrap web app zip
my $tmpfile = download_file("http://cdn.acugis.com/postgis/docs.tar.bz2");
if(!$tmpfile){
return 1;
}
#unzip extension to temp dir
print "<hr>Extracting docs ...<br>";
exec_cmd("tar -x --overwrite -f \"$tmpfile\" -C\"$www_dir\"");
&exec_cmd("chown -R $www_user:$www_user '$www_dir'");
open(my $fh, '>', "$module_config_directory/bootstraped.txt") or die "open:$!";
print $fh "Installed\n";
close $fh;
print "Done<br>";
return 0;
}
sub check_pg_ext_deps{
my $pg_ver = $_[0];
my @ext_pkgs;
if( ($osinfo{'os_type'} =~ /debian/i)){
@ext_pkgs = ("postgresql-$pg_ver-pgrouting-scripts", "postgresql-$pg_ver-pgrouting");
}elsif( $osinfo{'os_type'} =~ /redhat/i){
my $pg_ver2;
($pg_ver2 = $pg_ver) =~ s/\.//;
my $postgis_pkg = get_postgis_pkg_name($pg_ver);
@ext_pkgs = ($postgis_pkg, "pgrouting_$pg_ver2", "postgresql$pg_ver2-contrib");
}
my @pkg_missing;
foreach my $pkg (@ext_pkgs){
my @pinfo = software::package_info($pkg);
if(!@pinfo){
push(@pkg_missing, $pkg);
}
}
if(@pkg_missing){
my $url_pkg_list = '';
foreach my $pkg (@pkg_missing){
$url_pkg_list .= '&u='.&urlize($pkg);
}
my $pkg_list = join(', ', @pkg_missing);
print "<p>Warning: Missing PG package dependencies - $pkg_list packages are not installed. Install them manually or ".
"<a href='../package-updates/update.cgi?mode=new&source=3${url_pkg_list}&redir=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS'>click here</a> to have them installed.</p>";
}
}
sub get_dir_files{
my $dirpath = $_[0];
my $pattern = $_[1];
opendir(DIR, $dirpath) or die $!;
my @files = grep {
/^$pattern\./ # Starts with pattern
&& -f "$dirpath/$_" # and is a file
} readdir(DIR);
closedir(DIR);
return @files;
}
sub crunchy_load_countries(){
my $filename = download_file('https://www.naturalearthdata.com/http//www.naturalearthdata.com/download/50m/cultural/ne_50m_admin_0_countries.zip');
my $zip_dir = unzip_me($filename);
print "Renaming ne_50m_admin_0_countries to countries ...</br>";
my @data_files = get_dir_files($zip_dir, 'ne_50m_admin_0_countries');
foreach my $filename (@data_files){
(my $name, $ext) = split('\.', $filename);
&rename_file($zip_dir.'/'.$filename, $zip_dir.'/countries.'.$ext);
&set_ownership_permissions($crunchy_user, $crunchy_user, 0755, $zip_dir.'/countries.'.$ext);
}
print 'Importing ne_50m_admin_0_countries ...';
exec_cmd('shp2pgsql -I -s 4326 -W "latin1" '.$zip_dir.'/countries.shp countries | sudo -u '.$crunchy_user.' psql -d '.$crunchy_db);
&unlink_file($zip_dir);
}
sub setup_crunchy_db(){
#add user if it doesn exist
if(read_file_contents('/etc/passwd') !~ /\n$crunchy_user:/){
local $out = &backquote_command('useradd -m '.$crunchy_user, 0);
}
#generate password
my @pw_chars = ("A".."Z", "a".."z", "0".."9", "_", "-");
$db_pass .= $pw_chars[rand @pw_chars] for 1..32;
#setup database and user for qwc2
my $s = &postgresql::execute_sql_safe(undef, "CREATE USER $crunchy_user WITH PASSWORD '$db_pass' SUPERUSER");
$s = &postgresql::execute_sql_safe(undef, "CREATE DATABASE $crunchy_db WITH OWNER = $crunchy_user ENCODING = 'UTF8'");
$s = &postgresql::execute_sql_safe($crunchy_db, "CREATE EXTENSION postgis");
print "<p>Created database $crunchy_db and user $crunchy_user</p>";
#save password for qgis
my $pg_pass = '/home/'.$crunchy_user.'/.pgpass';
open(my $fh, '>', $pg_pass) or return 1;
print $fh "$crunchy_db:$crunchy_user:$db_pass\n";
close $fh;
&set_ownership_permissions($crunchy_user, $crunchy_user, 0600, $pg_pass);
#load the data
crunchy_load_countries();
}
sub update_toml{
my $app_name = $_[0];
my $toml_file = '/opt/'.$app_name.'/config/'.$app_name.'.toml';
#create the config file
&rename_file($toml_file.'.example', $toml_file);
#update the PG connection string in .toml file
my $ln = 0;
$lref = read_file_lines($toml_file);
foreach $line (@$lref){
chomp $line;
if($line =~ /^# DbConnection/){ #if its a section start
@{$lref}[$ln] = 'DbConnection = "postgresql://'.$crunchy_user.':'.$db_pass.'@localhost/'.$crunchy_db.'"';
}elsif($line =~ /^AssetsPath /){
@{$lref}[$ln] = 'AssetsPath = "/opt/'.$app_name.'/assets"';
}
$ln=$ln+1;
}
&flush_file_lines($toml_file);
}
sub install_pg_tileserv(){
my $app_home='/opt/pg_tileserv';
#download app
print "Downloading app ...</br>";
my $filename = &download_file('https://postgisftw.s3.amazonaws.com/pg_tileserv_latest_linux.zip');
my $unzip_dir = unzip_me($filename);
&rename_file($unzip_dir, $app_home);
update_toml('pg_tileserv');
#create the service file
print "Adding service file <b>pg_tileserv.service</b>...</br>";
open(my $fh, '>', '/etc/systemd/system/pg_tileserv.service') or die "open:$!";
print $fh '[Unit]'."\n";
print $fh 'Description=PG TileServ'."\n";
print $fh 'After=multi-user.target'."\n";
print $fh "\n";
print $fh '[Service]'."\n";
print $fh 'User='.$crunchy_user."\n";
print $fh 'WorkingDirectory='.$app_home."\n";
print $fh 'Type=simple'."\n";
print $fh 'Restart=always'."\n";
print $fh 'ExecStart='.$app_home.'/pg_tileserv'."\n";
print $fh "\n";
print $fh '[Install]'."\n";
print $fh 'WantedBy=multi-user.target'."\n";
close $fh;
exec_cmd('chown -R '.$crunchy_user.':'.$crunchy_user.' '.$app_home);
exec_cmd('systemctl daemon-reload');
exec_cmd('systemctl enable pg_tileserv');
exec_cmd('systemctl start pg_tileserv');
}
sub install_pg_featureserv(){
my $app_home='/opt/pg_featureserv';
#download app
print "Downloading app ...</br>";
my $filename = &download_file('https://postgisftw.s3.amazonaws.com/pg_featureserv_latest_linux.zip');
my $unzip_dir = unzip_me($filename);
&rename_file($unzip_dir, $app_home);
#create the environment file
my $crunchy_env = '/etc/default/crunchy_env';
if(! -f $crunchy_env){
print "Adding env file <b>/etc/default/crunchy_env</b>...</br>";
open(my $fh, '>', $crunchy_env) or die "open:$!";
print $fh 'DATABASE_URL=postgresql://'.$crunchy_user.'@localhost:5432/'.$crunchy_db."\n";
close $fh;
}
update_toml('pg_featureserv');
#create the service file
print "Adding service file <b>pg_featureserv.service</b>...</br>";
open(my $fh, '>', '/etc/systemd/system/pg_featureserv.service') or die "open:$!";
print $fh '[Unit]'."\n";
print $fh 'Description=PG FeatureServ'."\n";
print $fh 'After=multi-user.target'."\n";
print $fh "\n";
print $fh '[Service]'."\n";
print $fh 'User='.$crunchy_user."\n";
print $fh 'WorkingDirectory='.$app_home."\n";
print $fh 'Type=simple'."\n";
print $fh 'Restart=always'."\n";
print $fh 'ExecStart='.$app_home.'/pg_featureserv --config '.$app_home.'/config/pg_featureserv.toml'."\n";
print $fh "\n";
print $fh '[Install]'."\n";
print $fh 'WantedBy=multi-user.target'."\n";
close $fh;
exec_cmd('chown -R '.$crunchy_user.':'.$crunchy_user.' '.$app_home);
exec_cmd('systemctl daemon-reload');
exec_cmd('systemctl enable pg_tileserv');
exec_cmd('systemctl start pg_featureserv');
}
sub setup_checks{
if($osinfo{'real_os_type'} =~ /centos/i){ #CentOS
my @pinfo = software::package_info('epel-release', undef, );
if(!@pinfo){
print "<p>Warning: EPEL repository is not installed. Install it manually or ".
"<a href='../software/install_pack.cgi?source=3&update=epel-release&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>click here</a> to have it downloaded and installed.</p>";
}
}
my @mod_pkgs;
if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora
($osinfo{'real_os_type'} =~ /scientific/i) ){
@mod_pkgs = ('httpd', 'unzip', 'bzip2', 'tar');
}elsif( ($osinfo{'real_os_type'} =~ /ubuntu/i) or
($osinfo{'real_os_type'} =~ /debian/i) ){ #ubuntu or debian
@mod_pkgs = ('apache2', 'unzip', 'bzip2', 'tar');
}
foreach my $pkg (@mod_pkgs){
my @pinfo = software::package_info($pkg, undef, );
if(!@pinfo){
print "<p>Warning: $pkg not found. Install it manually or ".
"<a href='../package-updates/update.cgi?mode=new&source=3&u=$pkg&redir=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS'>click here</a> to have it downloaded and installed.</p>";
}
}
#Check if bootstrap web application is installed
if (! -f "$module_config_directory/bootstraped.txt"){
print '<p>Option: Bootstrap web app is not installed in /var/www/html. '.
"<a href='setup.cgi?mode=install_bootstrap_web_app&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> install it";
}
# Check if OpenLayers exists
if ((! -f "$module_config_directory/dismiss_openlayers.txt") &&
(! -d "/var/www/html/OpenLayers") ){
print "<p>Option: The OpenLayers direcrory <tt>/var/www/html/OpenLayers</tt> does not exist. ".
"<a href='setup.cgi?mode=install_openlayers&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> install it";
}
# Check if LeafletJS exists
if ((! -f "$module_config_directory/dismiss_leafletjs.txt") &&
(! -d "/var/www/html/leafletjs") ){
print "<p>Option: The LeafletJS directory <tt>/var/www/html/leafletjs</tt> does not exist. ".
"<a href='setup.cgi?mode=install_leafletjs&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> install it";
}
my $pg_ver = get_installed_pg_version();
if(have_pg_repo() == 0){
print '<p>Warning: PostgreSQL repository not found. Install it from <a href="./pg_install.cgi">'.$text{'pg_inst_title'}.'</a>';
}else{
if (!&has_command('shp2pgsql')) {
my $shp2pg_pkg = get_shp2pgsql_pkg_name($pg_ver);
if(-f "$module_root_directory/pg_install.cgi"){
print '<p>Warning: shp2pgsql command is not found.';
if(!$pg_ver){
print 'Install PG repo from <a href="./pg_install.cgi">'.$text{'pg_inst_title'}.'</a> and after that ';
}
print "<a href='../package-updates/update.cgi?mode=new&source=3&u=$shp2pg_pkg&redir=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS'>Click here</a> to have it installed from postgis package.</p>";
}else{
print '<p>Warning: shp2pgsql command is not found. '.
"<a href='../package-updates/update.cgi?mode=new&source=3&u=$shp2pg_pkg&redir=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS'>Click here</a> to have it installed from postgis package.</p>";
}
}
check_pg_ext_deps($pg_ver);
my $pg_ver2;
($pg_ver2 = $pg_ver) =~ s/\.//;
my %cmd_pkg;
if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora
($osinfo{'real_os_type'} =~ /scientific/i) ){
$cmd_pkg{'osm2pgsql'} = 'osm2pgsql';
$cmd_pkg{'osm2pgrouting'} = 'osm2pgrouting_'.$pg_ver2;
}elsif( ($osinfo{'real_os_type'} =~ /ubuntu/i) or
($osinfo{'real_os_type'} =~ /debian/i) ){ #ubuntu or debian
$cmd_pkg{'osm2pgsql'} = 'osm2pgsql';
$cmd_pkg{'osm2pgrouting'} = 'osm2pgrouting';
}
foreach my $cmd (keys %cmd_pkg){
if(!has_command($cmd)){
my $pkg = $cmd_pkg{$cmd};
print "<p>Warning: $cmd not found. Install it manually or ".
"<a href='../package-updates/update.cgi?mode=new&source=3&u=$pkg&redir=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS'>click here</a> to have it downloaded and installed.</p>";
}
}
if(foreign_installed('postgresql', 1) != 2){
print '<p>Warning: Webmin Postgresql module is not installed! Set it up from <a href="../postgresql/">here</a><p>';
}
}
if(! -f '/home/'.$crunchy_user.'/.pgpass'){
print "<p>Option: Crunchy PostgreSQL Database doesn't exist. ".
"<a href='setup.cgi?mode=setup_crunchy_db&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> create it";
}
if(! -d '/opt/pg_tileserv'){
print "<p>Option: pg_tileserv not installed. ".
"<a href='setup.cgi?mode=install_pg_tileserv&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> install it";
}
if(! -d '/opt/pg_featureserv'){
print "<p>Option: pg_featureServ not installed. ".
"<a href='setup.cgi?mode=install_pg_featureserv&return=%2E%2E%2Fpostgis%2Fsetup.cgi&redirdesc=PostGIS&caller=postgis'>Click here</a> install it";
}
print '<p>If you don\'t see any warnings above, you can complete setup by clicking '.
"<a href='setup.cgi?mode=cleanup&return=%2E%2E%2Facugis_es%2F&returndesc=AcuGIS%20ES&caller=acugis_es'>here</a></p>";
}
#Remove all setup files
sub setup_cleanup{
my $file = $module_root_directory.'/setup.cgi';
print "Completing Set Up....</br>";
&unlink_file($file);
print &js_redirect("index.cgi");
}
&ui_print_header(undef, $text{'setup_title'}, "");
if($ENV{'CONTENT_TYPE'} =~ /boundary=(.*)$/) {
&ReadParseMime();
}else {
&ReadParse(); $no_upload = 1;
}
my $mode = $in{'mode'} || "checks";
%osinfo = &detect_operating_system();
if( ( $osinfo{'real_os_type'} =~ /centos/i) or #CentOS
($osinfo{'real_os_type'} =~ /fedora/i) or #Fedora
($osinfo{'real_os_type'} =~ /scientific/i) ){
$www_user = 'apache';
}
if($mode eq "checks"){ setup_checks();
&ui_print_footer('', $text{'index_return'});
exit 0;
}elsif($mode eq "cleanup"){ setup_cleanup();
&ui_print_footer('', $text{'index_return'});
exit 0;
}elsif($mode eq "install_bootstrap_web_app"){ install_bootstrap_web_app();
}elsif($mode eq "install_openlayers"){ install_openlayers();
}elsif($mode eq "install_leafletjs"){ install_leafletjs();
}elsif($mode eq "setup_crunchy_db"){ setup_crunchy_db();
}elsif($mode eq "install_pg_tileserv"){ install_pg_tileserv();
}elsif($mode eq "install_pg_featureserv"){ install_pg_featureserv();
}else{
print "Error: Invalid setup mode\n";
}
&ui_print_footer('setup.cgi', $text{'setup_title'});