Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This is an experimental installer for WebGUI8 that attempts to use the
system package manager rather than the WRE. It currently targets
CentOS and Debian.
It is currently incomplete -- it doesn't set up WebGUI to run at boot
time on Debian, and it doesn't set up log rotation, or cron to run
wremonitor, and a few other things.
To run it installer on CentOS, do this, as root:
yum install wget
yum install perl
wget https://gist.githubusercontent.com/scrottie/2973558/raw/webgui_installer.pl --no-check-certificate
perl webgui_installer.pl
To run it installer on Debian, do this, as root:
apt-get install wget
apt-get install perl
wget https://gist.githubusercontent.com/scrottie/2973558/raw/webgui_installer.pl --no-check-certificate
perl webgui_installer.pl
It uses a Curses interface, asking the user about install options
(paths and passwords and such), and getting confirmation before running
commands.
It has been at points successfully tested on Debian 32 bit and CentOS 64
bit.
It asks for your sudo password and attempts to use that if run as a user,
but this is less well tested. There's some goo in the code for attempting
a user level permission install but that's incomplete. For now, running
as root is recommended. Update -- sudo mode is currently broken.
Curses, Curses::UI, and the setupfiles and docs directory are bundled
into the __DATA__ section of the webgui_installer.pl script. If changes
are made to those files in the github repo, the __DATA__ section of
the installer needs to be updated with uuencoded copies.
NO WARRANTY:
This script is provided without warranty, including warranty for
merchantability, suitability for any purpose, and is not warrantied against
special or incidental damages. It may not work, and it may
even break things. Use at your own risk! Always have go
od backups. Consult the included file docs/license.txt and source for
full copyright and license.
logs
passwd
shadow
mysqldata
rm -rf /data
rm -f /etc/nginx/conf.d/webgui8.conf
rm -f /etc/rc.d/*/*webgui8
rm -rf /tmp/WebGUICache
killall starman
mysql --user=root --password=Nyklm6 -e 'drop database www_example_com;'
# apt-get remove -y percona-server-server-5.5
####################################################################
# WebGUI License #
####################################################################
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/x-javascript js;
application/atom+xml atom;
application/rss+xml rss;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;
text/csv csv;
image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
image/webp webp;
application/java-archive jar war ear;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rdf+xml rdf;
application/rtf rtf;
application/vnd.ms-excel xls;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tar tar;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/zip zip;
application/octet-stream bin exe dll so ;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream eot;
application/octet-stream iso img;
application/octet-stream msi msp msm;
audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;
video/3gpp 3gpp 3gp;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime qt mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
webgui/package wgpkg;
}
user [% $run_as_user %];
worker_processes 10;
error_log [% log_files %]/nginx_error.log;
pid [% pid_files %]/nginx.pid;
events {
worker_connections 1024;
}
http {
include [% webgui_root %]/etc/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
server_tokens off;
gzip on;
gzip_types text/plain text/css application/json application/json-rpc application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9;
##Include per-server vhost configuration files.
include [% webgui_root %]/etc/*.nginx;
}
##Force all domain requests, mysite.com, to go to www.mysite.com
[% IF domain_name_has_www %]
server {
server_name [% domain_sans_www %];
rewrite ^ $scheme://[% domain %]$request_uri redirect;
}
[% END %]
server {
server_name [% sitename %];
listen 80; ## listen for ipv4
# access_log [% domainRoot %]/[% sitename %]/logs/access.log combined;
access_log [% log_files %]/[% sitename %].access.log combined;
root [% domainRoot %]/[% sitename %]/public;
client_max_body_size 20M;
# proxy webgui to starman listening on 127.0.0.1
location / {
# proxy_cache static;
# proxy_cache_valid 200 1s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:[% webgui_port %];
}
location /extras/ {
add_header Cache-Control public;
expires 24h;
root /data/WebGUI/www/;
add_header Access-Control-Allow-Origin *;
}
location /uploads/filepump { expires max; }
location = /default.ida { access_log off; deny all; }
location /_vti_bin { access_log off; deny all; }
location /_mem_bin { access_log off; deny all; }
location ~ /\.(ht|wg) { access_log off; deny all; }
location = /alive { access_log off; }
}
#server {
# listen 443;
# server_name [% sitename %] [%domain %];
#
# ssl on;
# ssl_certificate [% domainRoot %]/[% sitename %]/certs/server.crt;
# ssl_certificate_key [% domainRoot %]/[% sitename %]/certs/server.key;
#
# ssl_session_timeout 5m;
#
# ssl_protocols SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
# ssl_prefer_server_ciphers on;
#
# access_log [% domainRoot %]/[% sitename %]/logs/access.log combined
# root [% domainRoot %]/www.example.com/public;
#
# # proxy webgui to starman listening on 127.0.0.1
# location / {
# # proxy_cache static;
# # proxy_cache_valid 200 1s;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_set_header Host $host;
# proxy_pass http://127.0.0.1:[% webgui_port %];
# }
#
# location /extras/ {
# add_header Cache-Control public;
# expires 24h;
# root /data/WebGUI/www/extras;
# add_header Access-Control-Allow-Origin *;
# }
#
# location /uploads/filepump { expires max; }
# location = /default.ida { access_log off; deny all; }
# location /_vti_bin { access_log off; deny all; }
# location /_mem_bin { access_log off; deny all; }
# location ~ /\.(ht|wg) { access_log off; deny all; }
# location = /alive { access_log off; }
#}
#!/bin/bash
# chkconfig: 2345 90 60
# description: Start and stop WebGUI (non-WRE) plack-based service
# processname: webgui
export PERL5LIB="$PERL5LIB:[% webgui_root %]/lib"
export PATH="$PATH:/usr/local/bin" # starman gets installed into here
# See how we were called.
case "$1" in
start)
cd [% webgui_root %]
starman --pid=[% pid_files %]webgui.pid --quiet --port=[% webgui_port %] --preload-app --access-log=[% log_files %]/access_log --error-log=[% log_files %]/error_log --user=[% run_as_user %] --daemonize --start all
;;
stop)
kill `cat [% pid_files %]/webgui.pid`
;;
# restart)
# /data/wre/sbin/wreservice.pl --quiet --restart all
# ;;
*)
echo $"WebGUI Service Controller"
echo $"Usage:"
echo $" $0 { start | stop }"
exit 1
esac
exit $?
#!/usr/local/bin/perl
# to run this installer on CentOS, do:
# yum install wget
# yum install perl
# wget https://raw.github.com/gist/2973558/webgui_installer.pl --no-check-certificate
# perl webgui_installer.pl
# to run this installer on Debian, do:
# apt-get install wget
# apt-get install perl
# wget https://raw.github.com/gist/2973558/webgui_installer.pl --no-check-certificate
# perl webgui_installer.pl
# The full README is here:
# https://raw.github.com/gist/2973558/README
# And the full license is here:
# https://raw.github.com/gist/2973558/docs/license.txt
=for comment
-------------------------------------------------------------------
WebGUI is Copyright 2001-2012 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
based in part on git://gist.github.com/2318748.git:
run on a clean debian stable
install webgui 8, using my little tweaks to get things going.
bash/perl handling magic from http://www.perlmonks.org/?node_id=825147
xdanger
XXX todo:
XXXXX add instructions for starting spectre into the startup .sh we generate and check the hostname to make sure it resolves to the host (otherwise spectre won't work)
XXX plebgui support
XXX don't overwrite an existing nginx.conf without permission
XXX warn about impossiblely early date time; Curses wouldn't build
XXX service startup stuff on Debian, nginx config on Debian
XXX sudo mode hasn't been tested recently and is almost certainly broken
XXX check for spaces and other things in filenames and complain about them
XXX our /tmp install Curses bootstrap attempt is pathetic; should use local::lib perhaps
XXX on 64 bit debian, use the 64 bit specific package names!
XXX run() should take a 'requires root' flag and that should prompt the user to run things in a root terminal if not root
and there's no sudo password
XXX error if a 'webgui' user already exists -- don't reset the password! ... where did this logic go? had to re-write it
XXX /home/scott/bin/perl WebGUI/sbin/wgd reset --upgrade -- really not sure that's running and doing anything
XXX app.psgi should probably just do a 'use libs "extlib"' so that the user doesn't have to set up the local lib
TODO:
* Report on passwords created for various accounts at the end of the install
* Does it make sense to install one system-wide plack/starman startup file? Doesn't handle multiple installations but maybe does multiple sites on one install even though they all share logs? Or does it make more sense to install one system startup file for each site installed?
* setupfiles/wre.logrotate is unusused by us; do Debian and RedHat rotate mysql logs? probably. anyway, we probably also need to rotate the webgui.log.
* in verbose mode, put commands up for edit in a textbox with ok and cancel buttons
* maybe start script as a shell script then either unpack a perl script or self perk <<EOF it
* offer help for modules that won't install
* use WRE libs to do config file instead? depends on the wre.conf, hard-codes in the prereqs path, other things
* cross-reference this with my install instructions
* save/restore variables automatically since we're asking for so many things? tough for passwords though
* don't just automatically apt-get install perlmagick; handle system perl versus source install of perl scenarios
* take command line arg options for the various variables we ask the user so people can run this partially or non interactively
* ultra-low verbosity (fully automatic) mode
* would be awesome if this could diagnose and repair common problems
* even without using the WRE library code, look for mysql and such things in $install_root/wre and use them if there?
done/notes:
$run_as_user never gets changed from eg root; need to offer to create a webgui user; thought I had logic around to do that; chown $install_dir to them so that they can write log and pid files there, and chown -R uploads to them; useradd <username> --password <whatever>
MEVENT is getting typedef'd to int by default in the Curses code but ncurses wants to create the type. apparently it's a mouse event. clearing C_GETMOUSE should get rid of the offending code, maybe. swapping order of things seems to work, too. include'ing ncurses.h before CursesTyp.h sets C_TYPMEVENT so that it doesn't default to define'ing it as an int.
if something fails, offer to report the output of the failed command and the config variables (except for the last part)
add webgui to the system startup! I think there's something like this in the WRE -- testing
=cut
use strict;
use warnings;
no warnings 'redefine';
use IO::Handle;
use Config;
use File::Find;
use FindBin qw($Bin);
my $perl;
#
# some probes
#
# are we root?
my $root;
BEGIN { $root = $> == 0; };
# which linux
my $linux;
BEGIN {
$linux = 'unknown';
$linux = 'debian' if -f '/etc/debian_version';
$linux = 'redhat' if -f '/etc/redhat-release';
};
use Cwd;
# my $starting_dir = getcwd;
# $starting_dir only makes sense if the user did a git clone of the repo; if the script is to extract its own attachments, /tmp makes more sense
BEGIN { chdir '/tmp' or die $!; };
my $starting_dir = '/tmp/';
my $sixtyfour;
my $thirtytwo;
my $cpu;
BEGIN {
# early bootstrapping
$perl = $Config{perlpath};
$sixtyfour = $Config{archname} =~ m/x86_64/ ? '64' : ''; # XXXXXXX use these everywhere apt-get gets run
$thirtytwo = $Config{archname} =~ m/i686/ ? '32' : '';
$cpu = $Config{archname};
$cpu =~ s{-.*}{};
$cpu = 'i686' if $cpu eq 'i386'; # at least for RedHat
my $sudo = $root ? '' : `which sudo` || '';
chomp $sudo;
print "WebGUI8 installer bootstrap: Installing stuff before we install stuff...\n\n";
if( $linux eq 'debian' ) {
my $cmd = "$sudo apt-get update";
print "running: $cmd\nHit Enter to continue or Control-C to abort or 's' to skip.\n\n";
goto skip_update if readline(STDIN) =~ m/s/;
system $cmd;
skip_update:
$cmd = "$sudo apt-get install -y build-essential libncurses5-dev libcurses-perl libcurses-widgets-perl";
print "\n\nrunning: $cmd\nHit Enter to continue or Control-C to abort or 's' to skip.\n\n";
goto skip_apt_get if readline(STDIN) =~ m/s/;
system $cmd;
skip_apt_get:
} elsif( $linux eq 'redhat' ) {
# no counterpart to libcurses-perl or libcurses-widgets-perl so we have to fallback on building from the bundled tarball
my $cmd = "$sudo yum install --assumeyes gcc make automake kernel-devel man ncurses-devel.$cpu perl-devel.$cpu sudo";
print "running: $cmd\nHit Enter to continue or Control-C to abort or 's' to skip.\n\n";
goto skip_install if readline(STDIN) =~ m/s/;
system $cmd;
skip_install:
} else {
die "I only know how to do Debian and RedHat right now. Please refer to the source install instructions.\n";
}
# extract the uuencoded, tar-gzd attachments
do {
open my $data, '<', "$Bin/$0" or die "can't open $Bin/$0: $!"; # huh, so DATA isn't open yet in the BEGIN block, so we have to do this
# chdir '/tmp' or die $!; # chdir right after opening ourselves... okay, FindBin obviates that need
while( my $line = readline $data ) {
chomp $line;
last if $line =~ m/^__DATA__$/;
}
die if eof $data;
while( my $line = readline $data ) {
chomp $line;
next unless my ($mode, $file) = $line =~ m/^begin\s+(\d+)\s+(\S+)/;
open my $fh, '>', $file or die "can't create $file: $!";
while( my $line = readline $data ) {
chomp $line;
last if $line =~ m/^end/;
$line = unpack 'u', $line;
next unless defined $line and length $line;
$fh->print($line) or die $! if length $line;
}
}
};
# attempt to load Curses and Curses::Widget or go the backup plan -- try to build and install the bundled Curses/Curses::Widgets into /tmp
eval { require Curses; require Curses::Widgets; } or do {
`which make` or die 'Cannot bootstrap. Please install "make" (eg, apt-get install make) and try again.';
if( ! $root ) {
# this is a failed attempt at dealing with lack of root permission to install perl modules
# add to the library path before, so that after Curses is installed, Curses::Widgets can find it during build
my $v = '' . $^V;
$v =~ s{^v}{};
eval qq{ use lib "/tmp/lib/perl5/site_perl/$v/${sixtyfour}${thirtytwo}-linux/"; };# Curses.pm in there
eval qq{ use lib "/tmp/lib/perl5/"; };# no, Curses.pm is in here!
eval qq{ use lib "/tmp/lib/perl5/site_perl/$v/"; }; # Curses/Widgets.pm in there
eval qq{ use lib "/tmp/lib/perl5/auto/"; }; # no, Curses/Widgets.pm goes in there! no, it doesn't even... sigh
}
for my $filen ( 'Curses-1.28.modified.tar.gz', 'CursesWidgets-1.997.tar.gz' ) {
my $file = $filen;
system 'tar', '-xzf', $file and die $@;
$file =~ s{\.tar\.gz$}{};
$file =~ s{\.modified}{};
chdir $file or die $!;
die "Curses::Widgets not bootstrapping into a private lib directory on RedHat currently, sorry" if $linux eq 'redhat' and ! $root;
# XXX would be better to test -w on the perl lib dir; might be a private perl install
if( ! $root ) {
system $perl, 'Makefile.PL', 'PREFIX=/tmp';
} else {
system $perl, 'Makefile.PL';
}
system 'make' and die $@;
system 'make', 'install' and die $@;
chdir '..' or die $!;
}
# find all of the directories in /tmp and add them to the start of @INC
# XXX this is miserable
# XXX if there's a .pm in there, such as in Config/JSON.pm, and we add the Config dir, trying load JSON will load the JSON from Config::JSON and things will blow up
# XXX need some heuristic to deal with that -- look at the package line of stuff in the module and don't load it if has a :: in it? look for a VERSION string and don't add the dir if it doesn't have one?
# XXX alternatively, just hard-code where Curses and Curses::Widgets get installed at. argh.
#File::Find::find(
# sub {
# # unshift so we find our new crud before anything already installed
# unshift @INC, $File::Find::name if -d $_;
# },
# '/tmp',
#);
};
}
# use lib '/tmp/lib/perl5/site_perl'; # doesn't wind up in any constant place... grr!
use Curses;
use Curses::Widgets;
use Curses::Widgets::TextField;
use Curses::Widgets::ButtonSet;
use Curses::Widgets::TextMemo;
use Curses::Widgets::ListBox;
use Curses::Widgets::Calendar;
use Curses::Widgets::ComboBox;
use Curses::Widgets::Menu;
use Curses::Widgets::Label;
use Curses::Widgets::ProgressBar;
use Carp;
use IO::Select;
use IPC::Open3;
# use WRE::Config;
# use WRE::Site;
# use Config::JSON; # no relation to Config; argh, uses Moose; that makes it hard to bundle
use File::Copy 'cp';
use FileHandle;
#
#
#
my $verbosity = 1;
#
my $mwh = Curses->new;
noecho();
halfdelay(5);
$mwh->keypad(1);
$mwh->syncok(1);
curs_set(0);
leaveok(1);
sub main_win {
# main window
$mwh->erase();
# This function selects a few common colours for the foreground colour
$mwh->attrset(COLOR_PAIR(select_colour(qw(white black))));
$mwh->box(ACS_VLINE, ACS_HLINE);
$mwh->attrset(0);
$mwh->standout();
$mwh->addstr(0, 1, "WebGUI8");
$mwh->standend();
}
main_win();
#
# comment box and progress bar is always on the screen but never in focus
#
my $progress = do {
my ($y, $x);
$mwh->getmaxyx($y, $x);
Curses::Widgets::ProgressBar->new({
Y => $y - 16,
X => 1,
MIN => 0,
MAX => 100,
LENGTH => $x - 4,
FOREGROUND => 'white',
BACKGROUND => 'black',
BORDER => 1,
BORDERCOL => 'white',
CAPTION => 'Progress',
CAPTIONCOL => 'white',
});
};
my $comment_box_width;
my $comment = do {
my ($y, $x);
# Get the main screen max y & X
$mwh->getmaxyx($y, $x);
$comment_box_width = $x - 2;
Curses::Widgets::Label->new({
CAPTION => 'Comments',
BORDER => 1,
LINES => 10,
COLUMNS => $x - 4,
Y => $y - 13,
X => 1,
# VALUE => qq{ },
FOREGROUND => 'white',
BACKGROUND => 'black',
});
};
#
#
#
sub update {
my $message = shift() || '';
$message =~ s{^\n}{};
$message =~ s{^ +}{};
$message =~ s{\n +}{\n}g;
$comment->setField( VALUE => $message ) if $message;
$comment->draw($mwh);
$progress->draw($mwh);
}
sub progress {
my $percent = shift;
# $progress->input($hop) if $hop;
$progress->setField( VALUE => $percent ) if $percent;
$progress->draw($mwh);
}
sub bail {
my $message = shift;
update( $message . "\nHit Enter.\n");
scankey($mwh );
update( "May I please post this message to http://slowass.net/~scott/wginstallerbug.cgi?\nDoing so may help get bugs fixed and problems worked around in future versions." );
my $feedback_dialogue = Curses::Widgets::ListBox->new({
Y => 2,
X => 38,
COLUMNS => 20,
LISTITEMS => ['Yes', 'No'],
VALUE => 0,
SELECTEDCOL => 'white',
CAPTION => 'Send Feedback?',
CAPTIONCOL => 'white',
FOCUSSWITCH => "\t\n",
});
$feedback_dialogue->draw($mwh);
$feedback_dialogue->execute($mwh);
my $feedback = $feedback_dialogue->getField('CURSORPOS');
main_win(); # erase the dialogue
update(); # redraw after erasing the text dialogue
if( $feedback == 0 ) {
use Socket;
socket my $s, 2, 1, 6 or die $!;
connect $s, scalar sockaddr_in(80, scalar inet_aton("slowass.net")) or do {print "failed to send feedback: $!"; exit; };
$message =~ s{([^a-zA-Z0-9_-])}{ '%'.sprintf("%02x", ord($1)) }ge;
my $postdata = 'message=' . $message;
syswrite $s, "POST /~scott/wginstallerbug.cgi HTTP/1.0\r\nHost: slowass.net\r\nContent-type: application/x-www-form-urlencoded\r\nContent-Length: " . length($postdata) . "\r\n\r\n" . $postdata;
}
endwin();
print $message;
exit 1;
}
sub tail {
my $text = shift;
my $num_lines = 10;
split_again:
my @lines = split m/[\n\r]+/, $text;
for my $line (@lines) {
if( length($line) > $comment_box_width ) {
substr $line, $comment_box_width, 0, "\n";
$text = join "\n", @lines;
goto split_again;
}
}
@lines = @lines[ - $num_lines .. -1 ] if @lines > $num_lines;
return join "\n", @lines;
}
sub run {
# runs shell commands; verifies command with the user; collects error messages and shows them to the user
my $cmd = shift;
my %opts = @_;
my $noprompt = delete $opts{noprompt};
my $nofatal = delete $opts{nofatal};
my $input = delete $opts{input};
my $background = delete $opts{background};
$noprompt = 1 if $verbosity < 0; # ultra-low verbosity; only text boxes and such get shown
die join ', ', keys %opts if keys %opts;
my $msg = $comment->getField('VALUE');
if( ! $noprompt) {
update( $msg . qq{\nRunning '$cmd'.\nHit Enter to continue, press "s" to skip this command, or control-C to abort the script.} );
my $key = scankey($mwh);
if( $key =~ m/s/i ) {
update( $msg ); # restore original message from before we added stuff
return 1;
} else {
update( $msg . "\nWorking...\n" );
}
} else {
update( $msg . "\nRunning '$cmd'." );
}
if( $background ) {
if( ! fork ) {
# child process
exec $cmd;
} else {
sleep 3;
main_win(); update(); # redraw
return 1;
}
}
#open my $fh, '-|', "$cmd 2>&1" or bail(qq{
# $msg\nRunning '$cmd'\nFailed: $!
#});
my $pid = open3( my $to_child, my $fh, my $fh_error, $cmd ) or bail(qq{
$msg\nRunning '$cmd'\nFailed: $!
});
$to_child->print($input) if $input; # XXX to be safe, this would have to be done in an event loop or fork
my $exit = '';
close $to_child or $exit = $! ? "Error closing pipe: $!" : "Exit status $? from pipe";
my $output = '';
my $sel = IO::Select->new();
$sel->add($fh);
$sel->add($fh_error);
while (my @read_fhs = $sel->can_read()) {
# well that's miserable... IO::Select won't select on read and error at the same time
#while(1) {
#
# my $read_bits = $sel->[IO::Select::VEC_BITS];
# my $error_bits = $sel->[IO::Select::VEC_BITS];
# select( $read_bits, undef, $error_bits, undef );
# my @read_fhs = $sel->handles($read_bits);
# my @error_fhs = $sel->handles($error_bits);
my $buf;
for my $handle (@read_fhs) {
# handle may == $fh or $fh_error
my $handle_name = $handle == $fh ? 'STDOUT' : $handle == $fh_error ? 'STDERR' : 'unknown';
my $bytes_read = sysread($handle, $buf, 1024);
if ($bytes_read == -1) {
# $output .= "\n[Child's $handle_name closed]\n"; # XXX debug
$sel->remove($handle);
next;
}
if ($bytes_read == 0) {
# $output .= "\n[Child's $handle_name read error]\n"; # XXX
$sel->remove($handle);
next;
}
$output .= $buf;
}
# last if @error_fhs; # when the client starts closing stuff, it's done
update( tail( $msg . "\n$cmd:\n$output" ) );
}
# my $exit = close($output);
# close $to_child or $exit = $! ? "Error closing pipe: $!" : "Exit status $? from pipe";
waitpid $pid, 0;
$exit .= " Exit status @{[ $? >> 8 ]} from pipe" if $?;
if( $exit and ! $nofatal ) {
# XXX generate a failure report email in this case?
bail $msg . "\n$cmd:\n$output\nExit code $exit indicates failure." ;
} elsif( $exit and $nofatal ) {
update( tail( $msg . "\n$cmd:\n$output\nExit code $exit indicates failure.\nHit Enter to continue." ) );
scankey($mwh);
update( $msg ); # get rid of the extra stuff so that the next call to run() doesn't just keep adding stuff
return;
} else {
$output ||= 'Success.';
if( ! $noprompt and $verbosity >= 1 ) {
update( tail( $msg . "\n$cmd:\n$output\nHit Enter to continue." ) );
scankey($mwh);
}
update( $msg ); # get rid of the extra stuff so that the next call to run() doesn't just keep adding stuff
# if( scankey($mwh) =~ m/h/ ) { open my $fh, '|-', '/usr/bin/hexdump', '-C'; $fh->print($output); }; # this didn't work
}
# the call to run testEnvironment.pl in particular wants the command output
$output;
}
sub text {
my $title = shift;
my $value = shift;
my $text = Curses::Widgets::TextField->new({
Y => 4,
X => 1,
COLUMNS => 60,
MAXLENGTH => 80,
FOREGROUND => 'white',
BACKGROUND => 'black',
VALUE => $value,
BORDERCOL => 'white',
BORDER => 1,
CAPTION => $title,
CAPTIONCOL => 'white',
});
$text->draw($mwh);
$text->execute($mwh);
main_win(); # erase the text dialogue
update(); # redraw after erasing the text dialogue
return $text->getField('VALUE');
}
#
#
#
$SIG{CONT} = sub {
main_win(); # erase the dialogue
update(); # redraw after erasing the text dialogue
};
$SIG{USR1} = sub {
use Carp; Carp::confess $_[0];
};
#
#
#
do {
update(qq{
Welcome to the WebGUI8 installer utility!
Currently supported platforms are Debian GNU/Linux and CentOS GNU/Linux.
You may press control-C at any time to exit.
Examine commands before they're run to make sure that they're what you want to do!
Press any reasonable key to begin.
});
scankey($mwh);
update(qq{
This script is provided without warranty, including warranty for merchantability, suitability for any purpose, and is not warrantied against special or incidental damages. It may not work, and it may even break things. Use at your own risk! Always have good backups. Consult the included source for full copyright and license.
Press any reasonable key to continue.
});
scankey($mwh);
update(qq{
The full license (GNU GPL v2) is available from https://raw.github.com/gist/2973558/docs/license.txt
By using this software, you agree to the terms and conditions of the license.
Press any reasonable key to continue.
});
scankey($mwh);
update(qq{
Do you want to skip questions that have pretty good defaults?
You'll still be given a chance to inspect any potentially dangerous commands before they're run.
});
my $verbosiy_dialogue = Curses::Widgets::ListBox->new({
Y => 2,
X => 38,
COLUMNS => 25,
LISTITEMS => ['Fewer Questions', 'More Questions', 'Few Questions as Possible'],
VALUE => 0,
SELECTEDCOL => 'white',
CAPTION => 'Detail Level',
CAPTIONCOL => 'white',
FOCUSSWITCH => "\t\n",
});
$verbosiy_dialogue->draw($mwh);
$verbosiy_dialogue->execute($mwh);
$verbosity = $verbosiy_dialogue->getField('CURSORPOS');
$verbosity = -1 if $verbosity == 2;
main_win(); # erase the dialogue
update(); # redraw after erasing the text dialogue
};
# $SIG{__DIE__} = sub { bail("Fatal error: $_[0]\n"); };
# $SIG{__DIE__} = sub { endwin(); print "\n" x 10; Carp::confess($_[0]); };
$SIG{__DIE__} = sub { bail("Fatal error: $_[0]" . Carp::longmess() ); };
#
#
#
my $input_key = *Curses::Widgets::TextField::input_key{CODE};
*Curses::Widgets::TextField::input_key = sub {
my $self = shift;
my $key = shift;
$key = KEY_BACKSPACE if ord($key) == 127; # handle "delete" as "backspace"
$input_key->($self, $key);
};
#
# site name
#
my $site_name;
my $database_name;
do {
update(qq{
What domain name are you setting up this WebGUI for?
The config file, database, and directory of uploaded files will be named after this.
If you've already set up WebGUI and want to add another site, please instead use the addSite.pl utility.
This doesn't matter much if you're only setting up one site for development.
Most developers use "www.example.com" or "dev.localhost.localdomain".
});
$site_name = text( 'Domain name', 'www.example.com');
($database_name = $site_name) =~ s{\W}{_}g;
};
#
# /data directory
#
my $install_dir = $root ? '/data' : "$ENV{HOME}/webgui";
pick_install_directory:
do {
where_to_install:
$install_dir = text("Install Directory", $install_dir);
update(qq{
Where do you want to install WebGUI8?
Please enter an absolute path name (starting with a /).
The git repository will be checked out into a 'WebGUI' directory inside of there.
The configuration files will be placed inside of 'WebGUI/etc' in there.
Static and uploaded files for your site will be kept under in a 'domains' directory in there.
Traditionally, WebGUI has lived inside of the '/data' directory, but this is not necessary.
});
if( $verbosity >= 1 ) {
update(qq{
Create directory '$install_dir' to hold WebGUI? [Y/N]
});
goto where_to_install unless scankey($mwh) =~ m/^y/i;
}
main_win(); update(); # redraw
update( qq{Creating directory '$install_dir'.\n} );
run( "mkdir -p '$install_dir'", noprompt => 1 );
chdir $install_dir;
$ENV{PERL5LIB} .= ":$install_dir/WebGUI/lib:$install_dir/extlib/lib/perl5";
$ENV{WEBGUI_ROOT} = "$install_dir/WebGUI";
$ENV{WEBGUI_CONFIG} = "$install_dir/WebGUI/etc/$database_name.conf";
};
progress(5);
#
# sudo password
#
my $sudo_password = '';
my $sudo_command = '';
if( ! $root and `which sudo` ) {
sudo_command_again:
update( qq{
If you like, enter your account password to use to sudo various commands.
You'll be prompted before each command.
You may also skip entering your password here and manually complete the steps that require root access in another terminal window.
} );
$sudo_password = text( qq{sudo password}, '' ) or goto no_sudo_command;
# $sudo_command = "echo $sudo_password | sudo -S "; # prepended to stuff that needs to run as root XXX
$sudo_command = "sudo -S -- "; # prepended to stuff that needs to run as root
run( "$sudo_command ls /root", nofatal => 1, ) or goto sudo_command_again;
no_sudo_command:
} elsif( ! $root ) {
update( qq{
This script isn't running as root and I don't see sudo.
You'll be prompted to run commands as root in another terminal window when and if needed.
XXXXXX
Hit Enter to continue.
} );
scankey($mwh);
};
progress(10);
#
# var and log dirs
#
my $log_files = $install_dir or die;
my $pid_files = $install_dir or die;
if( $verbosity >= 1 ) {
# XXX should only ask this if some kind of a --verbose flag is on or if the user navigates here in a big menu of things to set
update(qq{
Into which directory should WebGUI and nginx write log files?
Writing into /var/log requires starting up as root.
WebGUI doesn't currently start as root and then drop privileges,
so /tmp or $install_dir are probably the best options.
});
$log_files = text( 'Log File Directory', $log_files );
update(qq{
Into which directory should nginx and starman write their PID file?
});
$pid_files = text( 'Log File Directory', $pid_files );
};
#
# port
#
my $webgui_port = 8081;
if( $verbosity >= 1 ) {
# XXX the wG listen port should probably also be firewalled off from the outside world
update(qq{
nginx listens on port 80 (HTTP requests go there first) and handles serving static files.
It proxies requests for dynamic content to WebGUI.
Which port should WebGUI listen on?
It should be higher than 1024 (so that WebGUI can start as a non-privileged user) and not already in use.
});
$webgui_port = text( 'WebGUI Listen Port', $webgui_port );
}
progress(15);
#
# mysqld
#
scan_for_mysqld:
my $mysqld_safe_path = `which mysqld_safe 2>/dev/null`; chomp $mysqld_safe_path if $mysqld_safe_path;
my $mysqld_path = `which mysqld 2>/dev/null`; chomp $mysqld_path if $mysqld_path;
if( $mysqld_safe_path and ! $mysqld_path ) {
# mysqld is probably hiding in a libexec somewhere and mysqld_safe won't relay a request for --version
open my $fh, '<', $mysqld_safe_path or bail "opening ``$mysqld_safe_path'', the mysqld_safe script, for read: $!";
while( my $line = readline $fh ) {
# looking for a line like this: ledir='/usr/local/libexec'
(my $ledir) = $line =~ m/^\s*ledir='(.*)'/ or next;
next if $ledir =~ m/\$/; # not any of the ones with shell variables in them; those run override args to mysqld_safe as given
$mysqld_path = $ledir . '/mysqld';
$mysqld_path = undef unless -x $mysqld_path;
}
}
my $mysqld_version;
if( $mysqld_path ) {
my $extra = '';
# if ! -x $mysqld_path # XXX
# update( $comment->getField('VALUE') . " Running command: $mysqld_path --version", noprompt => 1, );
# my $sqld_version = `$mysqld_path --version`;
$mysqld_version = run "$mysqld_path --version", noprompt => 1;
# /usr/local/libexec/mysqld Ver 5.1.46 for pc-linux-gnu on i686 (Source distribution)
($mysqld_version) = $mysqld_version =~ m/Ver\s+(\d+\.\d+)\./ if $mysqld_version;
}
my $mysql_root_password;
my $run_as_user = getpwuid($>);
my $current_user = $run_as_user;
if( $run_as_user eq 'root' ) {
my ($name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell, $expire) = getpwnam('webgui');
if( ! $name ) {
ask_about_making_a_new_user:
update "Create a user to run the WebGUI server process as?";
my $dialogue = Curses::Widgets::ListBox->new({
Y => 2,
X => 38,
COLUMNS => 20,
LISTITEMS => ['Yes', 'No'],
VALUE => 'webgui',
SELECTEDCOL => 'white',
CAPTION => 'Create a user?',
CAPTIONCOL => 'white',
FOCUSSWITCH => "\t\n",
});
if( $verbosity >= 1 ) {
$dialogue->draw($mwh);
$dialogue->execute($mwh);
main_win(); # erase the dialogue
update(); # redraw after erasing the text dialogue
} else {
# for low or super low verbosity, assume yes
$dialogue->setField('CURSORPOS', 0);
}
if( $dialogue->getField('CURSORPOS') == 0 ) {
ask_what_username_to_use_for_the_new_user:
$run_as_user = text('New Username', '') or goto ask_about_making_a_new_user;
if( $run_as_user =~ m/[^a-z0-9_]/ ) {
update "Create a new user to run the WebGUI server process as?\nUsername must be numbers, letters, and underscore, and should be lowercase.";
goto ask_what_username_to_use_for_the_new_user;
}
my $new_user_password = join('', map { $_->[int rand scalar @$_] } (['a'..'z', 'A'..'Z', '0' .. '9']) x 12);
run "useradd $run_as_user --password $new_user_password";
}
} else {
# webgui user does exist; use it
# XXX should ask and confirm that that's what the user wants
$run_as_user = 'webgui';
}
}
if( $mysqld_safe_path) {
# mysql already exists
my $extra_text= '';
$extra_text .= "MySQL installed at $mysqld_path is version $mysqld_version.\n" if $mysqld_path and $mysqld_version;
if( $verbosity >= 1 ) {
update(qq{
$extra_text
Found mysqld_safe at $mysqld_safe_path.
Using it.
Hit enter to continue.
});
scankey($mwh);
} else {
update(qq{
$extra_text
Found mysqld_safe at $mysqld_safe_path.
Using it.
});
}
#
# start mysqld if it isn't already running
do {
my $ps = `ps ax`;
if( $ps !~ m/mysqld/ ) {
bail "wait, thought we had a mysqld at this point, but we don't have a mysqld_safe_path with which to start mysqld" unless $mysqld_safe_path;
update(qq{Starting mysqld...});
run( qq{ $sudo_command $mysqld_safe_path }, input => $sudo_password, noprompt => 1, background => 1, );
}
};
goto already_have_possible_mysql_root_password if $mysql_root_password;
mysql_password_again:
update( qq{
Please enter your MySQL root password.
This will be used to create a new database to hold data for the WebGUI site, and to
create a user to associate with that database.
} );
$mysql_root_password = text('MySQL Root Password', '') or goto mysql_password_again;
main_win(); # erase the dialogue
update(); # redraw after erasing the text dialogue
already_have_possible_mysql_root_password:
update( qq{ Testing to see if the MySQL root password we have works. } );
run( "mysql --user=root --password=$mysql_root_password -e 'show databases'", noprompt => 1, nofatal => 1 ) or goto mysql_password_again;
# end of the scenario where we found a mysqld already installed and we just need to get the root password before we can continue
} else {
# install and set up MySQL
if( ( $root or $sudo_command ) and $linux eq 'debian' ) {
update(qq{
Installing Percona Server to satisfy MySQL dependency.
This step adds the percona repo to your /etc/apt/sources.list (if it isn't there already) and then
installs the packages percona-server-server-5.5 and libmysqlclient18-dev.
});
# percona mysql 5.5
run( "$sudo_command gpg --keyserver hkp://keys.gnupg.net --recv-keys 1C4CBDCDCD2EFD2A", input => $sudo_password, );
run( "$sudo_command gpg -a --export CD2EFD2A | $sudo_command apt-key add -", input => $sudo_password, );
if( ! `grep 'http://repo.percona.com/apt' /etc/apt/sources.list` ) {
# run( qq{ $sudo_command echo "deb http://repo.percona.com/apt squeeze main" >> /etc/apt/sources.list }, input => $sudo_passwrd, ); # doesn't work; the >> doesn't run inside of sudo
# cp '/etc/apt/sources.list', '/tmp/sources.list' or bail "Failed to copy /etc/apt/sources.list to /tmp: $!; this means that I can't add ``deb http://repo.percona.com/apt squeeze main'' to the list; please do yourself and try again";
cp '/etc/apt/sources.list', '/tmp/sources.list' or bail "Failed to copy /etc/apt/sources.list to /tmp: $!";
open my $fh, '>>', '/tmp/sources.list' or bail "Failed to open /tmp/sources.list for append";
$fh->print("deb http://repo.percona.com/apt squeeze main") or bail "write failed: $!";
$fh->close;
run( qq{ $sudo_command cp /tmp/sources.list /etc/apt/sources.list }, input => $sudo_password, );
}
run( $sudo_command . 'apt-get update' ); # needed since we've just added to the sources
# run( $sudo_command . 'apt-get install -y percona-server-server-5.5 libmysqlclient-dev' );
# run( $sudo_command . 'apt-get install -y -q percona-server-server-5.5 libmysqlclient18-dev' ); # no can do; Debian fires up a curses UI and asks for a root password to set, even with 'quiet' set, so just shell out
system( "echo $sudo_password | $sudo_command apt-get install -y percona-server-server-5.5 libmysqlclient18-dev" ); # system(), not run(), so have to do sudo the old way
$mwh = Curses->new; # re-init the screen (echo off, etc)
main_win(); update(); # redraw
# go look for mysqld again now that it should be installed
# this also gives the installer another chance to ask for the root password, which the user set as part of shelling out to apt-get
goto scan_for_mysqld;
} elsif( ( $root or $sudo_command ) and $linux eq 'redhat' ) {
# figure out if they have either mysql or percona and use whichever they have if they have one? only install one if they don't have either XXX
run( "$sudo_command yum install --assumeyes mysql.$cpu mysql-devel.$cpu mysql-server.$cpu" );
# or else
# run( "$sudo_command rpm -Uhv --skip-broken http://www.percona.com/downloads/percona-release/percona-release-0.0-1.i386.rpm" ); # -Uhv is upgrade, help, version...? seems odd... and nothing about aliasing mysql to percona but then after this, attempts to install mysql stuff install more percona stuff and things get wedged
# run( "$sudo_command yum install -y Percona-Server-{server,client,shared,devel}-55" );
# have to start mysqld; rpm doesn't do it
if( ! -f "/etc/sysconfig/network" ) {
# XXX sudo cat?
# 'chkconfig mysqld on' fails if /etc/sysconfig/network wasn't set by the installer; from looking at Google's results, this doesn't seem to be the uncommon problem that RedHat users claim
$root or bail "/etc/sysconfig/network doesn't exist; cannot proceed; other tools won't work; yell at CentOS/RedHat about it";
open my $fh, '>', '/etc/sysconfig/network' or bail "cannot write to /etc/sysconfig/network: $!";
$fh->print(<<EOF) or bail "writing to /etc/sysconfig/network: $!";
NETWORK=yes
HOSTNAME=localhost.localdomain
EOF
close $fh or bail "writing to /etc/sysconfig/network: $!";
}
run( "$sudo_command /sbin/chkconfig mysqld on" );
run( "$sudo_command /sbin/service mysqld start" ); # this initializes the database, when it works
update( qq{ Please pick a MySQL root password\nDon't forget to write it down. You'll need it to create other database and manage MySQL.} );
$mysql_root_password = text('MySQL Root Password', '');
update( qq{ Setting MySQL root password. } );
# run( qq{mysql --user=root -e "SET PASSWORD FOR 'root' = PASSWORD('$mysql_root_password'); SET PASSWORD FOR 'root'\@'localhost' = PASSWORD('$mysql_root_password') SET PASSWORD FOR 'root'\@'127.0.0.1' = PASSWORD('$mysql_root_password');" } );
run( "mysqladmin -u root password '$mysql_root_password'" );
} else {
update(qq{
MySQL/Percona not found. Please use another terminal window (or control-Z this one) to install one of them, and then hit enter to continue.
});
scankey($mwh);
goto scan_for_mysqld;
}
update( qq{ Deleting MySQL anonymous user. } );
run( qq{mysql --user=root --password=$mysql_root_password -e "drop user '';" } );
}
progress(20);
#
# create database and user
#
my $mysql_user_password = join('', map { $_->[int rand scalar @$_] } (['a'..'z', 'A'..'Z', '0' .. '9']) x 12);
do {
# XXX hard-coded database user name to 'webgui' for now and user has no say in what the password is
update(qq{Creating database and database user.});
run( qq{mysql --password=$mysql_root_password --user=root -e "create database $database_name"} );
run( qq{mysql --password=$mysql_root_password --user=root -e "grant all privileges on $database_name.* to webgui\@localhost identified by '$mysql_user_password'"} );
};
progress(25);
#
# other system packages we need: imagemagck, openssl, expat, git, curl, nginx
#
do {
if( $root or $sudo_command and ( $linux eq 'debian' or $linux eq 'redhat' ) ) {
if( $linux eq 'debian' ) {
# run( $sudo_command . 'apt-get update', noprompt => 1, );
# XXXX yes, but are we installing perlmagick for the *correct* perl install? not if they built their own perl
run( "$sudo_command apt-get install -y perlmagick libssl-dev libexpat1-dev git curl nginx" );
} elsif( $linux eq 'redhat' ) {
# XXX this installs a ton of stuff, including X, cups, icon themes, etc. what triggered that? can we avoid it?
run( " $sudo_command yum install --assumeyes ImageMagick-perl.$cpu openssl.$cpu openssl-devel.$cpu expat-devel.$cpu git curl" );
# http://wiki.nginx.org/Install:
# "Due to differences between how CentOS, RHEL, and Scientific Linux populate the $releasever variable, it is necessary to manually
# replace $releasever with either "5" (for 5.x) or "6" (for 6.x), depending upon your OS version."
# XXX prompt before doing this
# if( ! -f '/etc/yum.repos.d/nginx.repo' )
# XXX sudo cat?
my $fh;
open $fh, '<', '/etc/redhat-release' or bail "can't open /etc/redhat-release to figure out which version we are to set the correct nginx repo with: $!";
(my $version) = readline $fh;
close $fh;
(my $releasever) = $version =~ m/release (\d+)\./;
(my $redhatcentos) = $version =~ m/(redhat|centos)/i or bail "reading /etc/redhat-release, couldn't match (redhat|centos) in ``$version''";
$redhatcentos = lc $redhatcentos;
$redhatcentos = 'rhel' if $redhatcentos eq 'redhat'; # just guessing here
open $fh, '>', '/etc/yum.repos.d/nginx.repo' or bail "can't write to /etc/yum.repos.d/nginx.repo: $!";
my $cpu2 = $cpu; $cpu2 = 'i386' if $cpu2 eq 'i686'; # for crying out loud...
$fh->print(<<EOF);
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/$redhatcentos/$releasever/$cpu2/
gpgcheck=0
enabled=1
EOF
close $fh;
run( $sudo_command . 'yum install --assumeyes nginx' );
}
} else {
update( "WebGUI needs the perlmagick libssl-dev libexpat1-dev git curl and build-essential packages but I'm not running as root or I'm on a strange system so I can't install them; please either install these or else run this script as root." ); # XXXX
scankey($mwh);
}
};
progress(30);
#
# WebGUI git checkout
#
do {
update("Checking out a copy of WebGUI from GitHub...");
# https:// fails for me on a fresh Debian for want of CAs; use http:// or git://
my $url = 'http://github.com/plainblack/webgui.git';
if( -f '/root/WebGUI/.git/config' ) {
$url = '/root/WebGUI';
update("Debug -- doing a local checkout of WebGUI from /root/WebGUI; if this isn't what you wanted, move that aside.");
}
run( "git clone $url WebGUI", nofatal => 1, ) or goto pick_install_directory;
};
progress(40);
#
# fetch cpanm
#
if( -f '/root/cpanm.test') {
update( "Devel -- Installing the cpanm utility to use to install Perl modules from a cached copy" );
run "cp -a /root/cpanm.test WebGUI/sbin/cpanm", noprompt =>1;
} else {
update "Installing the cpanm utility to use to install Perl modules..." ;
run 'curl --insecure --location --silent http://cpanmin.us --output WebGUI/sbin/cpanm', noprompt => 1;
run 'chmod ugo+x WebGUI/sbin/cpanm', noprompt => 1;
}
progress(45);
#
# wgd
#
if( -f '/root/wgd.test' ) {
update( "Devel -- Installing the wgd utility from a cached copy" );
run "cp -a /root/wgd.test WebGUI/sbin/wgd", noprompt =>1;
} else {
update( "Installing the wgd (WebGUI Developer) utility to use to run upgrades...", noprompt => 1, );
try_wgd_again:
run( 'curl --insecure --location --silent http://haarg.org/wgd > WebGUI/sbin/wgd', nofatal => 1, ) or do {
update( "Installing the wgd (WebGUI Developer) utility to use to run upgrades... trying again to fetch..." );
goto try_wgd_again;
};
run 'chmod ugo+x WebGUI/sbin/wgd', noprompt => 1;
}
progress(50);
# Task::WebGUI
do {
update( "Installing required Perl modules..." );
if( $root or $sudo_command or -w $Config{sitelib_stem} ) {
# if it's a perlbrew perl and the libs directory is writable by this user, or we're root, or we have sudo, just
# install the module stright into the site lib.
# if it fails, hopefully it wasn't important or else testEnvironment.pl can pick up the slack
# XXX should send reports when modules fail to build
# these don't have noprompt because RedHat users are cranky about perl modules not coming through their package system and I promised them that I would let them approve everything significant before it happens; need an ultra-low-verbosity verbosity setting
run( "$sudo_command $perl WebGUI/sbin/cpanm -n IO::Tty --verbose", nofatal => 1, ); # this one likes to time out
run( "$sudo_command $perl WebGUI/sbin/cpanm -n Task::WebGUI", nofatal => 1, );
} else {
# backup plan is to build an extlib directory
mkdir "$install_dir/extlib"; # XXX moved this up outside of 'WebGUI'
run( "$perl WebGUI/sbin/cpanm -n -L $install_dir/extlib IO::Tty --verbose", nofatal => 1, ); # this one likes to time out
run( "$perl WebGUI/sbin/cpanm -n -L $install_dir/extlib Task::WebGUI", nofatal => 1, );
}
if( $linux eq 'redhat' ) {
run( "$sudo_command $perl WebGUI/sbin/cpanm -n CPAN --verbose", noprompt => 1, nofatal => 1, ); # RedHat's perl doesn't come with the CPAN shell
}
};
#
# testEnvironment.pl
#
do {
update( "Checking for any additional needed Perl modules..." );
# XXX Task::WebGUI
my $test_environment_output = run( "$perl WebGUI/sbin/testEnvironment.pl --noprompt --simpleReport", );
# XXX $test_environment_output or ... handle failure
# Checking for module Weather::Com::Finder: OK
my @results = grep m/Checking for module/, split m/\n/, $test_environment_output;
for my $result ( @results ) {
next if $result =~ m/:.*OK/;
$result =~ s{:\s+.*}{};
$result =~ s{Checking for module }{};
update( "Installing Perl module $result from CPAN:" );
if( $root or $sudo_command or -w $Config{sitelib_stem} ) {
# if it's a perlbrew perl and the libs directory is writable by this user, or we're root, or we have sudo, just
# install the module stright into the site lib.
run( "$sudo_command $perl WebGUI/sbin/cpanm -n $result", noprompt => 1, );
} else {
# backup plan is to build an extlib directory
mkdir "$install_dir/extlib"; # XXX moved this up outside of 'WebGUI'
run( "$perl WebGUI/sbin/cpanm -n -L $install_dir/extlib $result", noprompt => 1, );
}
}
};
# testEnviroment.pl/cpanm should have installed some modules that we need
do {
local $SIG{__DIE__};
eval "use Config::JSON;";
eval "use Template";
};
progress(60);
#
# create.sql syntax
#
# update("mysqld_version is $mysqld_version; changing sql syntax if >= 5.5"); scankey($mwh); # debug
if( $mysqld_version and $mysqld_version >= 5.5 ) {
# XXX what is the actual cut off point? is it 5.5, or something else?
# get a working create.sql because someone messed up the one in repo
# sdw: MySQL changed; there's no syntax that'll work with both new and old ones
update( 'Updating details in the create.sql to make MySQL/Percona >= 5.5 happy...' );
# scankey($mwh); # debug
run( $perl . ' -p -i -e "s/TYPE=InnoDB CHARSET=utf8/ENGINE=InnoDB DEFAULT CHARSET=utf8/g" WebGUI/share/create.sql ', noprompt => 1,);
run( $perl . ' -p -i -e "s/TYPE=MyISAM CHARSET=utf8/ENGINE=MyISAM DEFAULT CHARSET=utf8/g" WebGUI/share/create.sql ', noprompt => 1, );
};
progress(65);
#
# create database and load create.sql
#
do {
update( qq{
Loading the initial WebGUI database.
This contains configuration, table structure for all of the tables, definitions for the default assets, and other stuff.
} );
run( qq{ mysql --password=$mysql_user_password --user=webgui $database_name < WebGUI/share/create.sql }, noprompt => 1, );
};
#
# WebGUI config files
#
do {
# www.whatever.com.conf
# XXX change this to use $site_name, not $database_name, for the filename
# largely adapted from /data/wre/sbin/wresetup.pl
cp 'WebGUI/etc/WebGUI.conf.original', "WebGUI/etc/$database_name.conf" or bail "Failed to copy WebGUI/etc/WebGUI.conf.original to WebGUI/etc/$database_name.conf: $!";
cp 'WebGUI/etc/log.conf.original', 'WebGUI/etc/log.conf' or bail "Failed to copy WebGUI/etc/log.conf.original to WebGUI/etc/log.conf: $!";
my $config = Config::JSON->new( "WebGUI/etc/$database_name.conf" );
$config->set( dbuser => 'webgui', );
$config->set( dbpass => $mysql_user_password, );
$config->set( dsn => "DBI:mysql:${database_name};host=127.0.0.1;port=3306" ); # XXX faster if we use the mysql.sock?
$config->set( uploadsPath => "$install_dir/domains/$site_name/public/uploads", );
# $config->set( extrasPath => "$install_dir/domains/$site_name/public/extras", ); # XXX not currently copying this; make it match what we give nginx
$config->set( extrasPath => "$install_dir/WebGUI/www/extras", ); # XXX not currently copying this; make it match what we give nginx
$config->set( maintenancePage => "$install_dir/WebGUI/www/maintenance.html", );
# XXX the searchIndexPlugins scripts that come with the WRE
# log.conf
eval {
template(log_conf(), "$install_dir/WebGUI/etc/log.conf", { } )
} or bail "Failed to template log.conf to $install_dir/WebGUI/etc/log.conf: $@";
};
progress(70);
#
# create webroot
#
do {
# create webroot
update qq{Creating site directory structure under $install_dir/domains/$site_name... };
mkdir "$install_dir/domains" or bail "Couldn't create $install_dir/domains: $!";
mkdir "$install_dir/domains/$site_name" or bail "Couldn't create $install_dir/domains/$site_name: $!";
# mkdir "$install_dir/domains/$site_name/logs" or bail "Couldn't create $install_dir/domains/$site_name/logs: $!"; # not under /data/wre but instead in WebGUI and we let the user pick a dir earlier on
mkdir "$install_dir/domains/$site_name/public" or bail "Couldn't create $install_dir/domains/$site_name/public: $!";
mkdir "$install_dir/domains/$site_name/public/uploads" or bail "Couldn't create $install_dir/domains/$site_name/public/uploads: $!";
update qq{Populating $install_dir/domains/$site_name/public/uploads with bundled static HTML, JS, and CSS... };
run "$perl WebGUI/sbin/wgd reset --uploads", noprompt => 1;
# run "cp -a WebGUI/www/extras $install_dir/domains/public/", noprompt => 1; # matches $config->set( extrasPath => "$install_dir/domains/$site_name/public/extras", ), above # XXX nginx points into WebGUI/www/extras ...
run "chown $run_as_user $install_dir", noprompt => 1;
run "chown -R $run_as_user $install_dir/domains/$site_name/public/uploads", noprompt => 1;
};
progress(75);
#
# nginx config
#
do {
# create nginx config
# start nginx
update "Setting up nginx main config";
if( -f "/etc/nginx/conf.d/webgui8.conf" ) {
update "There's already an /etc/nginx/conf.d/webgui8.conf; not overwriting it (have I been here before?).\nHit Enter to continue.";
scankey($mwh);
} else {
# nginx.conf does an include [% webgui_root %]/etc/*.nginx
eval {
template(nginx_conf(), "/etc/nginx/conf.d/webgui8.conf", { } ) # XXX this is on CentOS; is it the same on Debian?
} or bail "Failed to template nginx.conf to etc/nginx/conf.d/webgui8.conf: $@";
}
if( -f '/etc/nginx/conf.d/default.conf' ) {
update "Remove the default, stock nginx config file? Don't remove it if you've made changes to it and are using it!";
run "rm /etc/nginx/conf.d/default.conf"; # XXX this is on CentOS; is it the same on Debian?
}
update "Setting up nginx per-site config";
# addsite.pl does this as a two-step process
# $file->copy($config->getRoot("/var/setupfiles/nginx.template"), $config->getRoot("/var/nginx.template"), { force => 1 });
# $file->copy($wreConfig->getRoot("/var/nginx.template"), $wreConfig->getRoot("/etc/".$sitename.".nginx"), { templateVars => $params, force => 1 });
# XXX we're putting $sitename.nginx in WebGUI/etc, not wre/etc; probably have to change the main nginx.conf to match; yup, testing
eval {
template(nginx_template(), "$install_dir/WebGUI/etc/$database_name.nginx", { } )
} or bail "Failed to template nginx.template to $install_dir/WebGUI/etc/$database_name.nginx: $@";
if( ! -f "$install_dir/WebGUI/etc/mime.types" ) {
update "Setting up mime.types file, which is needed by nginx";
# cp "$starting_dir/setupfiles/mime.types", "$install_dir/WebGUI/etc/mime.types" or
# bail "Copying $starting_dir/setupfiles/mime.types to $install_dir/WebGUI/etc/mime.types failed: $@";
open my $fh, '>', "$install_dir/WebGUI/etc/mime.types" or
bail "Failed to open $install_dir/WebGUI/etc/mime.types for write: $!";
# $fh->print(mime_types()) or bail "Writing $install_dir/WebGUI/etc/mime.types failed; $!"; # is there a problem with the one it comes with?
$fh->close or bail "Writing $install_dir/WebGUI/etc/mime.types failed; $!";
}
update "Having nginx test nginx.conf and the conf files it pulls in";
run "nginx -t", noprompt => 1;
if( $linux eq 'debian' ) {
# XXXX
} elsif( $linux eq 'redhat' ) {
run "$sudo_command /sbin/chkconfig nginx on", noprompt => 1 ;
run "$sudo_command /sbin/service nginx start", noprompt => 1 ;
}
};
#
# system startup files for webgui
#
do {
if( $linux eq 'debian' ) {
# eval {
# template(services_debian(), "/etc/rc.d/init.d/webgui8XXXX", { } ) # XXXXXXXX doesn't exist yet and certainly isn't tested
# } or bail "Failed to template startup file into /etc/rc.d/init.d/webgui8XXXX: $@";
# run "chmod ugo+x /etc/rc.d/init.d/webgui8", noprompt => 1; # XXXX
} elsif( $linux eq 'redhat' ) {
eval {
template(services_redhat(), "/etc/rc.d/init.d/webgui8", { } )
} or bail "Failed to template startup file into /etc/rc.d/init.d/webgui8: $@";
run "chmod ugo+x /etc/rc.d/init.d/webgui8", noprompt => 1;
}
};
progress(80);
#
# miserable hack
#
do {
# fix version number to match create.sql
update( qq{
Working around a release problem where upgrades refuse to run because of a version mismatch.
} );
run( $perl . ' -p -i -e "s/8\.0\.1/8\.0\.0/g" WebGUI/lib/WebGUI.pm', noprompt => 1, );
};
#
# upgrades
#
do {
update( qq{
Running upgrades.
Each release of WebGUI includes upgrade scripts that modify the database or config files.
However, a new config file and database dump are not included in each release, so upgrades
are necessary even for brand new installs.
} );
# run "$perl WebGUI/sbin/wgd reset --upgrade", noprompt => 1,; # XXX testing... want to watch the output of this... thought there were a lot more upgrades!
if( $run_as_user eq 'root' ) {
run "$perl WebGUI/sbin/wgd reset --upgrade";
} else {
# run upgrades as the user wG is going to run as so that log files, uploads, etc are all owned by that user
run "sudo -u $run_as_user $perl WebGUI/sbin/wgd reset --upgrade --config-file=$database_name.conf --webgui-root=$install_dir/WebGUI";
}
};
progress(90);
#
# start webgui
#
do {
update "Fixing log file permissions";
run "chown $run_as_user $log_files/*.log", noprompt => 1; # not sure how that winds up as root (during upgrades I guess) but not being able to write it was breaking things; running wgd --upgrade as $run_as_user now, after some pain, and this is still happening!
# still not enough... I guess webgui.log doesn't exist yet, gets created as owned by root, then plack tries to re-open it and fails; doing killall starman, rm webgui.log, service start starman seems to suggest that this is the case
run "touch $log_files/webgui.log", noprompt => 1;
run "chown $run_as_user $log_files/*.log", noprompt => 1; # testing... again after touching the file
if( $linux eq 'debian' ) {
# XXX
} elsif( $linux eq 'redhat' ) {
update "Attempting to start the WebGUI server process...\n";
run "$sudo_command /sbin/chkconfig webgui8 on", noprompt => 1 ;
run "$sudo_command /sbin/service webgui8 start", noprompt => 1, background => 1 ; # XXX working around this process going zombie
}
};
#
# parting comments
#
do {
#run webgui. -- For faster server install "cpanm -L extlib Starman" and add " -s Starman --workers 10 --disable-keepalive" to plackup command
# XXX should dynamically include a list of things the user needs to manually do
update( qq{
Installation is wrapping up.
Debian users will need to add a startup script to start WebGUI if they want it to start with the system.
$install_dir/webgui.sh shows how to manually launch WebGUI.
Documentation and forums are at http://webgui.org.
} );
scankey($mwh);
open my $fh, '>', "$install_dir/webgui.sh" or bail("failed to write to $install_dir/webgui.sh: $!");
$fh->print(<<EOF);
cd $install_dir/WebGUI
export PERL5LIB="\$PERL5LIB:$install_dir/WebGUI/lib"
plackup --port $webgui_port app.psgi &
EOF
close $fh;
progress(100);
# "If cpanm was able to install modules into the siteperl directory, this should work to test:"
# cd $install_dir/WebGUI
# export PERL5LIB="/$install_dir/WebGUI/lib"
# plackup --port $webgui_port app.psgi
update( qq{
Installation complete.
Go to http://$site_name and set up the new site.
The admin user is "Admin" with password "123qwe".
Please hit any reasonable key to exit the installer.
} );
scankey($mwh);
};
#
# goo
#
sub template {
my $infn = shift;
my $outfn = shift;
my $var = shift;
# $var->{config} = $config; # XXXX change references or else mock up an object
# $var->{wreRoot} = $config->getRoot; # doesn't seem to actually be used in the installfiles templates; however, config.getRoot is used and I think is the same thing, which is problematic
$var->{install_dir} = $install_dir;
$var->{webgui_root} = "$install_dir/WebGUI/";
$var->{domainRoot} = "$install_dir/domains/"; # this one is used
$var->{osName} = ($^O =~ /MSWin32/i || $^O=~ /^Win/i) ? "windows" : $^O;
$var->{database_name} = $database_name; # like sitename, but with the dots changed to underscores
$var->{sitename} = $site_name;
$var->{domain} = $site_name; $var->{domain} =~ s/[^.]+\.//;
$var->{domain_name_has_www} = ( $site_name =~ m/^www\./ ) ? 1 : 0;
$var->{domain_sans_www} = $site_name; $var->{domain_sans_www} =~ s{^www\.}{};
$var->{run_as_user} = $run_as_user;
$var->{pid_files} = $pid_files;
$var->{log_files} = $log_files;
$var->{webgui_port} = $webgui_port;
# open my $infh, '<', $infn or bail "templating out config files, couldn't open input file $infn: $!";
# read $infh, my $input, -s $infh;
# close $infh or die $!;
my $input = $infn; # moved to hard-coding the template data into the installer file
# XXX if not writeable by us, write to a temp file and then use sudo to move it into place
open my $outfh, '>', $outfn or bail "templating out config files, couldn't open output file $outfn: $!";
my $template = Template->new(INCLUDE_PATH=>'/');
$template->process(\$input, $var, \my $output) or die $template->error;
print $outfh $output or bail "templating out config files, couldn't write to the output file: $!";
close $outfh or bail "templating out config files, couldn't close the output file: $!";
}
END {
endwin();
}
#
# files needed for the wG install that aren't part of wG and don't come with it
#
sub nginx_conf {
<<'EOF';
# sendfile on; # duplicate with /etc/nginx/nginx.conf; causes a fatal error; have to trust that it's right in /etc/nginx/nginx.conf or else check that it's right in there
# gzip on; # in at least one report, duplicate with /etc/nginx/nginx.coknf; causes a fatal error
gzip_types text/plain text/css application/json application/json-rpc application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 5;
##Include per-server vhost configuration files.
include [% webgui_root %]/etc/*.nginx;
EOF
}
sub nginx_template {
<<'EOF';
##Force all domain requests, mysite.com, to go to www.mysite.com
[% IF domain_name_has_www %]
server {
server_name [% domain_sans_www %];
rewrite ^ $scheme://[% domain %]$request_uri redirect;
}
[% END %]
server {
server_name [% sitename %];
listen 80; ## listen for ipv4
# access_log [% domainRoot %]/[% sitename %]/logs/access.log combined;
access_log [% log_files %]/[% sitename %].access.log combined;
root [% domainRoot %]/[% sitename %]/public;
client_max_body_size 20M;
# proxy webgui to starman listening on 127.0.0.1
location / {
# proxy_cache static;
# proxy_cache_valid 200 1s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:[% webgui_port %];
}
location /extras/ {
add_header Cache-Control public;
expires 24h;
root [% webgui_root %]/www/;
add_header Access-Control-Allow-Origin *;
}
location /uploads/filepump { expires max; }
location = /default.ida { access_log off; deny all; }
location /_vti_bin { access_log off; deny all; }
location /_mem_bin { access_log off; deny all; }
location ~ /\.(ht|wg) { access_log off; deny all; }
location = /alive { access_log off; }
}
#server {
# listen 443;
# server_name [% sitename %] [%domain %];
#
# ssl on;
# ssl_certificate [% domainRoot %]/[% sitename %]/certs/server.crt;
# ssl_certificate_key [% domainRoot %]/[% sitename %]/certs/server.key;
#
# ssl_session_timeout 5m;
#
# ssl_protocols SSLv3 TLSv1;
# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
# ssl_prefer_server_ciphers on;
#
# access_log [% domainRoot %]/[% sitename %]/logs/access.log combined
# root [% domainRoot %]/www.example.com/public;
#
# # proxy webgui to starman listening on 127.0.0.1
# location / {
# # proxy_cache static;
# # proxy_cache_valid 200 1s;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $remote_addr;
# proxy_set_header Host $host;
# proxy_pass http://127.0.0.1:[% webgui_port %];
# }
#
# location /extras/ {
# add_header Cache-Control public;
# expires 24h;
# root /data/WebGUI/www/extras;
# add_header Access-Control-Allow-Origin *;
# }
#
# location /uploads/filepump { expires max; }
# location = /default.ida { access_log off; deny all; }
# location /_vti_bin { access_log off; deny all; }
# location /_mem_bin { access_log off; deny all; }
# location ~ /\.(ht|wg) { access_log off; deny all; }
# location = /alive { access_log off; }
#}
EOF
}
sub services_debian {
<<EOF;
XXXXXXXXXXXXXXXX
EOF
}
sub services_redhat {
<<'EOF';
#!/bin/bash
# chkconfig: 2345 90 60
# description: Start and stop WebGUI (non-WRE) plack-based service
# processname: webgui
export PERL5LIB="$PERL5LIB:[% webgui_root %]/lib"
export PATH="$PATH:/usr/local/bin" # starman gets installed into here
# See how we were called.
case "$1" in
start)
# sdw: I'm having a problem where the 'service' program goes zombie waiting for this to properly daemonize; XXX fix this
# nophup ... > [% log_files %]/starman.startup.log # didn't fix it
cd [% webgui_root %]
starman --pid=[% pid_files %]/webgui.pid --quiet --port=[% webgui_port %] --preload-app --access-log=[% log_files %]/access_log --error-log=[% log_files %]/error_log --user=[% run_as_user %] --daemonize
;;
stop)
kill `cat [% pid_files %]/webgui.pid`
;;
# restart)
# /data/wre/sbin/wreservice.pl --quiet --restart all
# ;;
*)
echo $"WebGUI Service Controller"
echo $"Usage:"
echo $" $0 { start | stop }"
exit 1
esac
exit $?
EOF
}
sub log_conf {
<<'EOF';
# WebGUI uses the log4perl logging system. This default configuration file
# will work out of the box and will log only ERROR and FATAL level messages to
# /var/log/webgui.log. This is only the beginning of what this logging
# system is capable of. To unleash the full power read the config file manual
# http://log4perl.sourceforge.net/releases/Log-Log4perl/docs/html/Log/Log4perl/Config.html
log4perl.logger = ERROR, mainlog
log4perl.appender.mainlog = Log::Log4perl::Appender::File
log4perl.appender.mainlog.filename = [% log_files %]/webgui.log
log4perl.appender.mainlog.layout = PatternLayout
log4perl.appender.mainlog.layout.ConversionPattern = %d - %p - %c - %M[%L] - %m%n
EOF
}
__DATA__
begin 666 Curses-1.28.modified.tar.gz
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