diff --git a/.gitignore b/.gitignore index 034741d03..753121a52 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ pm_to_blib mailer.testfile privatelib cover_db +.vagrant diff --git a/MANIFEST b/MANIFEST index 76ca5f9ec..d98e9f474 100644 --- a/MANIFEST +++ b/MANIFEST @@ -12,6 +12,7 @@ bin/make_user_account.pl bin/mirrormail.pl bin/paused bin/stats_for_neilb.pl +cpanfile cron/cleanup-incoming.pl cron/cron-daily.pl cron/CRONTAB.ROOT diff --git a/Makefile.PL b/Makefile.PL index 552b073bb..52c7767cd 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -2,102 +2,20 @@ use strict; use ExtUtils::MakeMaker; + +open( my $fh,'<','cpanfile' ) + || die "Couldn't open cpanfile to get deps: $!"; + +my @deps = map { ( split( /'/,$_ ) )[1]; } <$fh>; +close( $fh ); + WriteMakefile( NAME => 'PAUSE', VERSION_FROM => 'lib/PAUSE.pm', ABSTRACT_FROM => 'lib/PAUSE.pod', AUTHOR => 'Andreas Koenig ', LICENSE => 'perl', - PREREQ_PM => { map +($_ => 0), qw( - Apache::Session::Counted - BSD::Resource - Capture::Tiny - CPAN::Checksums - CPAN::DistnameInfo - CPAN::Indexer::Mirror - Class::MOP::Class - Class::Singleton - Compress::Zlib - Crypt::Eksblowfish::Bcrypt - Cwd - DB_File - DBD::mysql - DBD::SQLite - DBI - DBIx::RunSQL - Devel::Peek - Dumpvalue - Email::Address - Email::MIME - Email::Sender::Simple - EV - File::Copy::Recursive - File::pushd - File::Rsync::Mirror::Recentfile - File::Temp - File::Which - Git::Wrapper - HTML::Entities - HTTP::Date - HTTP::Request::Common - HTTP::Tiny - IO::Socket::SSL - IPC::Cmd - IPC::Run3 - JSON::XS - Log::Dispatch - Log::Dispatch::Config - LWP::UserAgent - LWP::Protocol::https - Digest::MD5 - Digest::SHA1 - Mail::Mailer - Mail::Send - Module::Faker::Dist - Module::Signature - Moo - Mojolicious - Mojolicious::Plugin::WithCSRFProtection - MojoX::Log::Dispatch::Simple - MooseX::StrictConstructor - Net::FTP - Net::SSLeay - Parse::CPAN::Packages - Parse::CPAN::Perms - Path::Class - Path::Tiny - Plack - Plack::App::Directory::Apaxy - Plack::Middleware::Auth::Basic - Plack::Middleware::ReverseProxy - Plack::Middleware::ServerStatus::Tiny - Set::Crontab - SQL::Maker - String::Random - Test::Class - Test::Deep - Test::FITesque::Fixture - Test::MockObject - Test::mysqld - Test::WWW::Mechanize::PSGI - Text::Format - Text::Markdown::Hoedown - Text::Metaphone - Text::Soundex - Text::Unidecode - Time::Duration - Time::HiRes - URI::Escape - URI::URL - Unicode::Collate - Unicode::String - WWW::Mechanize::Boilerplate - XML::LibXML - XML::Parser - XML::SAX::Base - XML::SAX::Writer - YAML::XS -)}, + PREREQ_PM => { map +($_ => 0), @deps }, SIGN => 1, test => { RECURSIVE_TEST_FILES => 1 }, ($ExtUtils::MakeMaker::VERSION >= 6.4502 ? diff --git a/README.md b/README.md new file mode 100644 index 000000000..c67411a88 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# PAUSE + +### The [Perl programming] Authors Upload Server + +[http://pause.perl.org/](http://pause.perl.org/) + +To build a development box you will need VirtualBox and Vagrant. + +git clone this repo then build the box that also install all necessary dependencies: + + VAGRANT_VAGRANTFILE=box-builder/Vagrantfile vagrant up + VAGRANT_VAGRANTFILE=box-builder/Vagrantfile vagrant halt + vagrant up --provision + +This make take around 30 minutes or so. Once the above is done you can: + + vagrant ssh + cd pause + perl Makefile.PL + make test + +And if tests pass: + + plackup -I ../pause-private/lib + +Or for the mojolicious based server: + + plackup -I ../pause-private/lib --path / app_2017.psgi + +You should then be able to access PAUSE on `https://192.168.56.1` + +For more information about setup, development, and deployment see `doc/README` diff --git a/Vagrantfile b/Vagrantfile new file mode 100644 index 000000000..e14cd1f60 --- /dev/null +++ b/Vagrantfile @@ -0,0 +1,31 @@ +ENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox' + +Vagrant.configure("2") do |config| + + config.vm.box = "debian/stretch64" + + # Use PAUSE_DEVELOPER_* env vars to set vm hardware resources. + vbox_custom = %w[cpus memory].map do |hw| + key = "PAUSE_DEVELOPER_#{hw.upcase}" + ENV[key] ? ["--#{hw}", ENV[key]] : [] + end.flatten + + config.vm.post_up_message = $msg + + config.vm.provider :virtualbox do |vb| + vb.name = "pause-stretch" + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + if not vbox_custom.empty? + vb.customize [ "modifyvm", :id, *vbox_custom ] + end + end + + config.vm.network "forwarded_port", guest: 80, host: 80 # apache http + config.vm.network "forwarded_port", guest: 443, host: 443 # apache https + config.vm.network "forwarded_port", guest: 5000, host: 5000 # PAUSE (non-TLS) + + config.vm.synced_folder '.', '/vagrant', disabled: true + config.vm.synced_folder ".", "/home/vagrant/pause" + + config.vm.provision :shell, :path => 'provision/all.sh' +end diff --git a/box-builder/Vagrantfile b/box-builder/Vagrantfile new file mode 100644 index 000000000..b8896b433 --- /dev/null +++ b/box-builder/Vagrantfile @@ -0,0 +1,43 @@ +ENV['VAGRANT_DEFAULT_PROVIDER'] = 'virtualbox' + +# To build a fresh box, from the top dir of this repository: +# +# * vagrant destroy +# * VAGRANT_VAGRANTFILE=box-builder/Vagrantfile vagrant up +# * VAGRANT_VAGRANTFILE=box-builder/Vagrantfile vagrant halt +# * vagrant up --provision +# +# To use more resources: +# PAUSE_DEVELOPER_CPUS=4 PAUSE_DEVELOPER_MEMORY=16384 VAGRANT_VAGRANTFILE=box-builder/Vagrantfile vagrant up + +Vagrant.configure("2") do |config| + config.vm.box = "debian/stretch64" + config.vm.hostname = "pause-dev" + +$msg = < 'box-builder/provision.sh' +end diff --git a/box-builder/provision.sh b/box-builder/provision.sh new file mode 100755 index 000000000..6f2c33f82 --- /dev/null +++ b/box-builder/provision.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -o errexit +set -e -o pipefail + +echo "vagrant provision: $0" + +# https://serverfault.com/a/500778/119512 +export LANGUAGE=en_US.UTF-8 +export LANG=en_US.UTF-8 +export LC_ALL=en_US.UTF-8 +locale-gen en_US.UTF-8 +dpkg-reconfigure --frontend=noninteractive locales + +apt-get update + +# some nice to haves for working on the box +apt-get -q --assume-yes install vim +apt-get -q --assume-yes install sudo +apt-get -q --assume-yes install openssh-server +apt-get -q --assume-yes install git +apt-get -q --assume-yes install aptitude +apt-get -q --assume-yes install curl + +# some must haves for running the app/installing CPAN deps +apt-get -q --assume-yes install default-libmysqlclient-dev +apt-get -q --assume-yes install libxml2-dev +apt-get -q --assume-yes install libexpat-dev +apt-get -q --assume-yes install libssl-dev + +# some must have for other required services +apt-get -q --assume-yes install mysql-server +apt-get -q --assume-yes install nginx +apt-get -q --assume-yes install unzip diff --git a/doc/README b/doc/README index 920a4657f..b620b8c31 100644 --- a/doc/README +++ b/doc/README @@ -43,7 +43,7 @@ Also, user ID's need to be B in both 'authen_pause' and 'mod'. You can set up the mod database from scratch like this: mysqladmin -uroot -p create mod - mysql -uroot -p authen_pause < doc/mod.schema.txt + mysql -uroot -p mod < doc/mod.schema.txt However, if you want to start with a copy of PAUSE's existing database, you can create the database, rsync a backup and restore it -- but beware diff --git a/provision/all.sh b/provision/all.sh new file mode 100755 index 000000000..b1af5d35f --- /dev/null +++ b/provision/all.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +# Execute all the scripts in a directory. +function exec_dir () { + local dir="$1" + [[ "${dir:0:1}" == "/" ]] || dir="/vagrant/provision/$dir" + for exe in "$dir"/*; do + test -x "$exe" && echo "# $exe" && "$exe" + done +} + +# Execute any before vm initialization scripts. +exec_dir before + +# Execute any after vm clean-up scripts. +exec_dir after + +# install CPAN dependencies, note we are using the system perl here... +cd /home/vagrant/pause +PERL_MM_USE_DEFAULT=1 cpan App::cpanminus +cpanm --installdeps . + +# database setup (note this is DEV setup hence simple passwords) +mysqladmin -u root password "mysql" + +mysqladmin -uroot -pmysql create mod +mysql -uroot -pmysql mod < doc/mod.schema.txt +mysql -uroot -pmysql mod -e 'insert into users (userid) values ("LEEJO")' + +mysqladmin -uroot -pmysql create authen_pause +mysql -uroot -pmysql authen_pause < doc/authen_pause.schema.txt + +LEEJO_PAUSE_PASSWD=$(perl -le 'print crypt "tiger","ef"') +mysql -uroot -pmysql authen_pause -e "insert into usertable (user,password) values ('LEEJO', '$LEEJO_PAUSE_PASSWD')" + +# in mysql5.7 root login for localhost changed from password style to +# sudo login style so we have to drop and recreate the root user to +# restore password style login from non-sudo +mysql -u root -pmysql -e " \ +DROP USER 'root'@'localhost'; \ +CREATE USER 'root'@'%' IDENTIFIED BY 'mysql'; \ +GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'mysql' WITH GRANT OPTION; \ +FLUSH PRIVILEGES; +"; + +# access to the databases +mkdir -p ../pause-private/lib + +cat >> ../pause-private/lib/PrivatePAUSE.pm <<"EndOfFile" +use strict; +package PAUSE; + +$ENV{EMAIL_SENDER_TRANSPORT} = 'DevNull'; + +our $Config; + +$Config->{AUTHEN_DATA_SOURCE_USER} = "root"; +$Config->{AUTHEN_DATA_SOURCE_PW} = "mysql"; +$Config->{MOD_DATA_SOURCE_USER} = "root"; +$Config->{MOD_DATA_SOURCE_PW} = "mysql"; +$Config->{MAIL_MAILER} = ["testfile"]; + +$Config->{RUNDATA} = "/tmp/pause_1999"; +$Config->{TESTHOST_SCHEMA} = "https"; + +1; +EndOfFile + +mkdir -p /tmp/pause_1999; + +# config for nginx +mkdir -p /usr/local/nginx/conf + +openssl req \ + -new \ + -newkey rsa:4096 \ + -days 365 \ + -nodes \ + -x509 \ + -subj "/C=CH/ST=Vaud/L=Villars/O=PAUSE/CN=pause.perl.org" \ + -keyout /usr/local/nginx/conf/server.key \ + -out /usr/local/nginx/conf/server.crt + +cp /home/vagrant/pause/doc/nginx-pause-config.sample /etc/nginx/sites-enabled/nginx-pause-config +nginx -s reload + +# Don't let vagrant think the provision failed. +exit 0 diff --git a/provision/before/fix_stdin_not_tty_message.sh b/provision/before/fix_stdin_not_tty_message.sh new file mode 100755 index 000000000..ce7924c66 --- /dev/null +++ b/provision/before/fix_stdin_not_tty_message.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +# Fix the `stdin: is not a tty` message. +sed -i 's/^mesg n$/tty -s \&\& mesg n/g' /root/.profile diff --git a/provision/before/hostname.sh b/provision/before/hostname.sh new file mode 100755 index 000000000..195ae89a8 --- /dev/null +++ b/provision/before/hostname.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +hostname=pause-dev + +# If we can't write files, give up now. +if ! touch /tmp/disk-writable; then + echo 'Failed to write to disk. Please try "vagrant reload"'; + exit 1; +fi + +# Set hostname in this session. +hostname "$hostname" +# Remember after reboot. +grep -qFx "$hostname" /etc/hostname || echo "$hostname" > /etc/hostname + +# Ensure there is an entry for each host name. +for host in $hostname localhost puppet; do + grep -qE "^127.0.[01].1[[:space:]]+.*$host" /etc/hosts || \ + echo "127.0.0.1 $host" >> /etc/hosts +done diff --git a/provision/common.bashrc b/provision/common.bashrc new file mode 100644 index 000000000..52399c6af --- /dev/null +++ b/provision/common.bashrc @@ -0,0 +1,16 @@ +# Vagrant shared directories get owned by the vagrant user +# but some programs need certain (usually sub-) dirs to be user-writable. +# Create tmp dirs and mount them on top of the share to work around this. +function change_shared_dir_owner () { + local user="$1" dest="$2" + local src="/tmp/v-share-mounts/$dest" + + mkdir -p "$dest" "$src" + chown "$user" "$src" + chmod g+w "$src" + + # Only proceed if not already mounted. + mount | grep -qF " $dest " && return + + mount --bind "$src" "$dest" +}