passenger 4.0.48 → 4.0.49
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- checksums.yaml +8 -8
- checksums.yaml.gz.asc +7 -7
- data.tar.gz.asc +7 -7
- data/.editorconfig +36 -2
- data/.travis.yml +1 -1
- data/CHANGELOG +16 -0
- data/Rakefile +0 -1
- data/build/apache2.rb +4 -4
- data/build/common_library.rb +18 -18
- data/build/cplusplus_support.rb +2 -2
- data/build/documentation.rb +1 -1
- data/build/integration_tests.rb +12 -4
- data/build/misc.rb +12 -7
- data/build/packaging.rb +14 -14
- data/build/preprocessor.rb +10 -10
- data/build/rake_extensions.rb +11 -11
- data/build/ruby_extension.rb +2 -2
- data/dev/ci/inituidgid +24 -0
- data/dev/ci/run_jenkins.sh +57 -0
- data/dev/ci/run_rpm_tests.sh +77 -0
- data/dev/{run_travis.sh → ci/run_travis.sh} +60 -4
- data/doc/Users guide Nginx.txt +2 -2
- data/doc/users_guide_snippets/environment_variables.txt +0 -2
- data/doc/users_guide_snippets/tips.txt +20 -1
- data/ext/apache2/Bucket.cpp +18 -18
- data/ext/apache2/Bucket.h +4 -4
- data/ext/apache2/Configuration.cpp +7 -7
- data/ext/apache2/Configuration.hpp +43 -43
- data/ext/apache2/DirectoryMapper.h +5 -5
- data/ext/apache2/Hooks.cpp +142 -142
- data/ext/apache2/MergeDirConfig.cpp +40 -40
- data/ext/common/Account.h +17 -17
- data/ext/common/AccountsDatabase.h +9 -9
- data/ext/common/AgentsStarter.cpp +2 -2
- data/ext/common/AgentsStarter.h +40 -40
- data/ext/common/ApplicationPool2/Common.h +10 -6
- data/ext/common/ApplicationPool2/ComponentInfo.h +2 -2
- data/ext/common/ApplicationPool2/DirectSpawner.h +17 -17
- data/ext/common/ApplicationPool2/DummySpawner.h +5 -5
- data/ext/common/ApplicationPool2/Group.h +54 -38
- data/ext/common/ApplicationPool2/Implementation.cpp +76 -49
- data/ext/common/ApplicationPool2/Options.h +98 -91
- data/ext/common/ApplicationPool2/Pool.h +70 -69
- data/ext/common/ApplicationPool2/Process.h +21 -21
- data/ext/common/ApplicationPool2/Session.h +11 -11
- data/ext/common/ApplicationPool2/SmartSpawner.h +60 -60
- data/ext/common/ApplicationPool2/Socket.h +19 -19
- data/ext/common/ApplicationPool2/Spawner.h +64 -72
- data/ext/common/ApplicationPool2/SpawnerFactory.h +4 -4
- data/ext/common/ApplicationPool2/SuperGroup.h +41 -41
- data/ext/common/BackgroundEventLoop.cpp +1 -1
- data/ext/common/BackgroundEventLoop.h +2 -2
- data/ext/common/Constants.h +1 -1
- data/ext/common/EventedBufferedInput.h +5 -5
- data/ext/common/EventedClient.h +51 -51
- data/ext/common/EventedMessageServer.h +39 -39
- data/ext/common/EventedServer.h +32 -32
- data/ext/common/Exceptions.h +23 -23
- data/ext/common/FileDescriptor.h +18 -18
- data/ext/common/Logging.cpp +1 -1
- data/ext/common/MessageClient.h +27 -27
- data/ext/common/MessageReadersWriters.h +79 -79
- data/ext/common/MessageServer.h +59 -59
- data/ext/common/RandomGenerator.h +12 -12
- data/ext/common/ResourceLocator.h +8 -8
- data/ext/common/SafeLibev.h +54 -25
- data/ext/common/ServerInstanceDir.h +31 -31
- data/ext/common/StaticString.h +50 -48
- data/ext/common/Utils.cpp +73 -78
- data/ext/common/Utils.h +6 -6
- data/ext/common/Utils/Base64.cpp +3 -3
- data/ext/common/Utils/Base64.h +7 -7
- data/ext/common/Utils/BlockingQueue.h +9 -9
- data/ext/common/Utils/BufferedIO.h +17 -17
- data/ext/common/Utils/CachedFileStat.hpp +16 -16
- data/ext/common/Utils/Dechunker.h +25 -25
- data/ext/common/Utils/FileChangeChecker.h +10 -10
- data/ext/common/Utils/MemZeroGuard.h +5 -5
- data/ext/common/Utils/MemoryBarrier.h +1 -1
- data/ext/common/Utils/MessageIO.h +61 -61
- data/ext/common/Utils/ProcessMetricsCollector.h +40 -40
- data/ext/common/Utils/ScopeGuard.h +7 -7
- data/ext/common/Utils/SpeedMeter.h +1 -1
- data/ext/common/Utils/StrIntUtils.cpp +13 -13
- data/ext/common/Utils/StrIntUtils.h +3 -3
- data/ext/common/Utils/StringScanning.h +5 -5
- data/ext/common/Utils/SystemMetricsCollector.h +2 -2
- data/ext/common/Utils/SystemTime.h +10 -10
- data/ext/common/Utils/Template.h +2 -2
- data/ext/common/Utils/Timer.h +6 -6
- data/ext/common/Utils/VariantMap.h +29 -29
- data/ext/common/agents/Base.cpp +19 -19
- data/ext/common/agents/HelperAgent/AgentOptions.h +1 -1
- data/ext/common/agents/HelperAgent/FileBackedPipe.h +6 -6
- data/ext/common/agents/HelperAgent/Main.cpp +44 -43
- data/ext/common/agents/HelperAgent/RequestHandler.cpp +4 -4
- data/ext/common/agents/HelperAgent/RequestHandler.h +29 -28
- data/ext/common/agents/HelperAgent/ScgiRequestParser.h +56 -50
- data/ext/common/agents/LoggingAgent/AdminController.h +8 -8
- data/ext/common/agents/LoggingAgent/DataStoreId.h +17 -17
- data/ext/common/agents/LoggingAgent/FilterSupport.h +167 -167
- data/ext/common/agents/LoggingAgent/LoggingServer.h +122 -122
- data/ext/common/agents/LoggingAgent/Main.cpp +7 -7
- data/ext/common/agents/LoggingAgent/RemoteSender.h +54 -54
- data/ext/common/agents/SpawnPreparer.cpp +4 -4
- data/ext/common/agents/TempDirToucher.c +2 -2
- data/ext/common/agents/Watchdog/AgentWatcher.cpp +47 -47
- data/ext/common/agents/Watchdog/HelperAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/LoggingAgentWatcher.cpp +7 -7
- data/ext/common/agents/Watchdog/Main.cpp +22 -22
- data/ext/common/agents/Watchdog/ServerInstanceDirToucher.cpp +9 -9
- data/ext/libeio/eio.c +1 -1
- data/ext/nginx/Configuration.c +30 -30
- data/ext/nginx/Configuration.h +1 -1
- data/ext/nginx/ContentHandler.c +54 -54
- data/ext/nginx/ContentHandler.h +3 -3
- data/ext/nginx/StaticContentHandler.c +2 -2
- data/ext/nginx/ngx_http_passenger_module.c +21 -21
- data/ext/oxt/detail/backtrace_enabled.hpp +1 -1
- data/ext/oxt/detail/context.hpp +1 -1
- data/ext/oxt/detail/spin_lock_darwin.hpp +4 -4
- data/ext/oxt/detail/spin_lock_gcc_x86.hpp +3 -3
- data/ext/oxt/detail/spin_lock_pthreads.hpp +4 -4
- data/ext/oxt/detail/tracable_exception_disabled.hpp +1 -1
- data/ext/oxt/dynamic_thread_group.hpp +18 -18
- data/ext/oxt/implementation.cpp +9 -8
- data/ext/oxt/macros.hpp +2 -2
- data/ext/oxt/system_calls.cpp +11 -11
- data/ext/oxt/system_calls.hpp +13 -13
- data/ext/oxt/thread.hpp +22 -14
- data/ext/ruby/passenger_native_support.c +55 -55
- data/lib/phusion_passenger.rb +24 -24
- data/lib/phusion_passenger/common_library.rb +2 -0
- data/lib/phusion_passenger/loader_shared_helpers.rb +18 -18
- data/lib/phusion_passenger/packaging.rb +9 -4
- data/lib/phusion_passenger/platform_info/apache.rb +45 -31
- data/lib/phusion_passenger/platform_info/compiler.rb +11 -11
- data/lib/phusion_passenger/rack/thread_handler_extension.rb +1 -1
- data/lib/phusion_passenger/request_handler/thread_handler.rb +8 -8
- data/lib/phusion_passenger/standalone/app_finder.rb +16 -16
- data/lib/phusion_passenger/standalone/command.rb +22 -22
- data/packaging/rpm/LICENSE.txt +19 -0
- data/packaging/rpm/Makefile +13 -0
- data/packaging/rpm/README.md +41 -0
- data/packaging/rpm/Vagrantfile +38 -0
- data/{rpm/Vagrantfile → packaging/rpm/Vagrantfile.centos} +0 -0
- data/packaging/rpm/build +170 -0
- data/packaging/rpm/create_project +41 -0
- data/packaging/rpm/git_update +88 -0
- data/packaging/rpm/image/Dockerfile +37 -0
- data/packaging/rpm/image/Gemfile +3 -0
- data/packaging/rpm/image/Gemfile.lock +12 -0
- data/packaging/rpm/image/RPM-GPG-KEY-amazon-ga +19 -0
- data/packaging/rpm/image/amazon2014-i386.cfg +96 -0
- data/packaging/rpm/image/amazon2014-x86_64.cfg +96 -0
- data/packaging/rpm/image/site-defaults.cfg +168 -0
- data/packaging/rpm/internal/build_tasks.rb +238 -0
- data/packaging/rpm/internal/dummygpg +11 -0
- data/packaging/rpm/internal/exec_build +42 -0
- data/packaging/rpm/internal/get_distro_arch +14 -0
- data/packaging/rpm/internal/get_distro_id +10 -0
- data/packaging/rpm/internal/git_update +27 -0
- data/packaging/rpm/internal/inituidgid +17 -0
- data/packaging/rpm/internal/my_init +344 -0
- data/packaging/rpm/internal/python27 +3 -0
- data/packaging/rpm/internal/repo_update +46 -0
- data/packaging/rpm/internal/setuser +26 -0
- data/packaging/rpm/internal/tracking_helper +40 -0
- data/packaging/rpm/jenkins_release +99 -0
- data/packaging/rpm/lib/build_tasks_support.rb +402 -0
- data/packaging/rpm/lib/preprocessor.rb +341 -0
- data/packaging/rpm/nginx_spec/404.html +119 -0
- data/packaging/rpm/nginx_spec/50x.html +119 -0
- data/packaging/rpm/nginx_spec/index.html +116 -0
- data/packaging/rpm/nginx_spec/nginx-auto-cc-gcc.patch +13 -0
- data/packaging/rpm/nginx_spec/nginx-logo.png +0 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade +13 -0
- data/packaging/rpm/nginx_spec/nginx-upgrade.8 +151 -0
- data/packaging/rpm/nginx_spec/nginx.conf +131 -0
- data/packaging/rpm/nginx_spec/nginx.init +144 -0
- data/packaging/rpm/nginx_spec/nginx.logrotate +13 -0
- data/packaging/rpm/nginx_spec/nginx.service +15 -0
- data/packaging/rpm/nginx_spec/nginx.spec.template +559 -0
- data/packaging/rpm/nginx_spec/nginx.sysconfig +4 -0
- data/packaging/rpm/nginx_spec/passenger.conf +9 -0
- data/packaging/rpm/nginx_spec/poweredby.png +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/apache-passenger.conf.in +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/config.json +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.logrotate +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger.spec.template +58 -31
- data/{rpm → packaging/rpm/passenger_spec}/passenger_dynamic_thread_group.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/passenger_tests_default_config_example.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-GLIBC_HAVE_LONG_LONG.patch +0 -0
- data/{rpm → packaging/rpm/passenger_spec}/rubygem-passenger-4.0.18-gcc47-include-sys_types.patch +0 -0
- data/packaging/rpm/repo_update +114 -0
- data/packaging/rpm/setup-system +60 -0
- data/packaging/rpm/shell +10 -0
- data/resources/templates/standalone/config.erb +3 -1
- data/test/config.json.rpm-automation +1 -1
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +11 -11
- data/test/cxx/ApplicationPool2/OptionsTest.cpp +5 -5
- data/test/cxx/ApplicationPool2/PoolTest.cpp +129 -89
- data/test/cxx/ApplicationPool2/ProcessTest.cpp +15 -15
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +22 -22
- data/test/cxx/ApplicationPool2/SpawnerTestCases.cpp +11 -11
- data/test/cxx/ScgiRequestParserTest.cpp +75 -61
- data/test/cxx/UtilsTest.cpp +86 -85
- data/test/gdbinit.example +3 -0
- data/test/integration_tests/nginx_tests.rb +3 -3
- data/test/integration_tests/source_packaging_test.rb +3 -1
- data/test/stub/nginx/nginx.conf.erb +8 -1
- data/test/support/nginx_controller.rb +7 -7
- metadata +62 -17
- metadata.gz.asc +7 -7
- data/build/rpm.rb +0 -128
- data/dev/rpmtool +0 -21
- data/dev/test_rpm_packaging.sh +0 -28
- data/rpm/get_distro_id.py +0 -4
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
/system/internal/inituidgid
|
5
|
+
|
6
|
+
### Import signing key.
|
7
|
+
/system/internal/setuser app /tools/silence-unless-failed \
|
8
|
+
gpg --batch --trust-model always --import /params/signing_key
|
9
|
+
|
10
|
+
### Make GPG non-interactive.
|
11
|
+
mv /usr/bin/gpg2 /usr/bin/gpg2.real
|
12
|
+
rm /usr/bin/gpg
|
13
|
+
cp /system/internal/dummygpg /usr/bin/gpg
|
14
|
+
|
15
|
+
### Sign packages.
|
16
|
+
echo " --> Signing packages"
|
17
|
+
/system/internal/setuser app \
|
18
|
+
rpm --resign --define '%_signature gpg' --define "%_gpg_name $SIGNING_KEY" \
|
19
|
+
/packages/*/*.rpm
|
20
|
+
|
21
|
+
### Import into repo.
|
22
|
+
cd /packages
|
23
|
+
PACKAGES=(*/*.rpm)
|
24
|
+
DIRS=()
|
25
|
+
echo " --> Importing ${#PACKAGES[*]} packages"
|
26
|
+
|
27
|
+
for F in "${PACKAGES[@]}"; do
|
28
|
+
DIR=`dirname "$F"`
|
29
|
+
DIRS+=("$DIR")
|
30
|
+
|
31
|
+
mkdir -p "/repo/$DIR"
|
32
|
+
echo " $F"
|
33
|
+
cp "$F" "/repo/$DIR/"
|
34
|
+
done
|
35
|
+
|
36
|
+
# $DIRS is now an array of distro-architecture directory names.
|
37
|
+
# We remove duplicates.
|
38
|
+
OUTPUT=`ruby -e 'puts ARGV.uniq.join("\n")' "${DIRS[@]}"`
|
39
|
+
IFS=$'\n'
|
40
|
+
DIRS=("$OUTPUT")
|
41
|
+
|
42
|
+
# Create a repo for each distro-architecture directory.
|
43
|
+
for DIR in ${DIRS[@]}; do
|
44
|
+
echo " --> Updating $DIR"
|
45
|
+
(cd "/repo/$DIR" && createrepo .)
|
46
|
+
done
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/system/internal/python27
|
2
|
+
import sys, os, pwd
|
3
|
+
|
4
|
+
if len(sys.argv) < 3:
|
5
|
+
sys.stderr.write("Usage: /sbin/setuser USERNAME COMMAND [args..]\n")
|
6
|
+
sys.exit(1)
|
7
|
+
|
8
|
+
def abort(message):
|
9
|
+
sys.stderr.write("setuser: %s\n" % message)
|
10
|
+
sys.exit(1)
|
11
|
+
|
12
|
+
username = sys.argv[1]
|
13
|
+
try:
|
14
|
+
user = pwd.getpwnam(username)
|
15
|
+
except KeyError:
|
16
|
+
abort("user %s not found" % username)
|
17
|
+
os.initgroups(username, user.pw_gid)
|
18
|
+
os.setgid(user.pw_gid)
|
19
|
+
os.setuid(user.pw_uid)
|
20
|
+
os.environ['USER'] = username
|
21
|
+
os.environ['HOME'] = user.pw_dir
|
22
|
+
os.environ['UID'] = str(user.pw_uid)
|
23
|
+
try:
|
24
|
+
os.execvp(sys.argv[2], sys.argv[2:])
|
25
|
+
except OSError as e:
|
26
|
+
abort("cannot execute %s: %s" % (sys.argv[2], str(e)))
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Adds timestamps to all lines on stdin, and prints them to stdout as well as a log file.
|
3
|
+
# The version printed to stdout has the specified prefix on each line.
|
4
|
+
|
5
|
+
set -e
|
6
|
+
set -o pipefail
|
7
|
+
|
8
|
+
PREFIX="$1"
|
9
|
+
LOGFILE="$2"
|
10
|
+
shift
|
11
|
+
shift
|
12
|
+
|
13
|
+
function cleanup()
|
14
|
+
{
|
15
|
+
local pids=`jobs -p`
|
16
|
+
set +e
|
17
|
+
if [[ "$pids" != "" ]]; then
|
18
|
+
kill $pids >/dev/null 2>/dev/null
|
19
|
+
fi
|
20
|
+
if [[ "$TEMPDIR" != "" ]]; then
|
21
|
+
rm -rf "$TEMPDIR"
|
22
|
+
fi
|
23
|
+
}
|
24
|
+
|
25
|
+
function add_timestamps()
|
26
|
+
{
|
27
|
+
gawk '{ print strftime("%Y-%m-%d %H:%M:%S --"), $0; fflush(); }'
|
28
|
+
}
|
29
|
+
|
30
|
+
function forward_multiple()
|
31
|
+
{
|
32
|
+
while read LINE; do
|
33
|
+
echo "$LINE" >&3
|
34
|
+
echo "${PREFIX}: ${LINE}"
|
35
|
+
done
|
36
|
+
}
|
37
|
+
|
38
|
+
trap cleanup EXIT
|
39
|
+
exec 3>>"$LOGFILE"
|
40
|
+
"$@" 2>&1 | add_timestamps | forward_multiple
|
@@ -0,0 +1,99 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -e
|
3
|
+
|
4
|
+
SELFROOT=`dirname "$0"`
|
5
|
+
SELFROOT=`cd "$SELFROOT" && pwd`
|
6
|
+
|
7
|
+
PROJECT_DIR=
|
8
|
+
PASSENGER_DIR=
|
9
|
+
CONCURRENCY=1
|
10
|
+
EXTRA_ARGS=
|
11
|
+
|
12
|
+
function run()
|
13
|
+
{
|
14
|
+
echo "$ $@"
|
15
|
+
"$@"
|
16
|
+
}
|
17
|
+
|
18
|
+
function cleanup()
|
19
|
+
{
|
20
|
+
set +e
|
21
|
+
local pids=`jobs -p`
|
22
|
+
if [[ "$pids" != "" ]]; then
|
23
|
+
kill $pids >/dev/null 2>/dev/null
|
24
|
+
fi
|
25
|
+
}
|
26
|
+
|
27
|
+
function usage()
|
28
|
+
{
|
29
|
+
echo "Usage: ./jenkins_release [OPTIONS]"
|
30
|
+
echo "Build RPMs and YUM repository. To be invoked from Jenkins."
|
31
|
+
echo
|
32
|
+
echo "Required options:"
|
33
|
+
echo " -p PATH Path to a project"
|
34
|
+
echo
|
35
|
+
echo "Optional options:"
|
36
|
+
echo " -P PATH Path to Phusion Passenger source directory"
|
37
|
+
echo " -j CONCURRENCY Build concurrency (default: $CONCURRENCY)"
|
38
|
+
echo " -O ARG Extra arguments to pass to build script"
|
39
|
+
}
|
40
|
+
|
41
|
+
function parse_options()
|
42
|
+
{
|
43
|
+
local OPTIND=1
|
44
|
+
local opt
|
45
|
+
while getopts "p:P:j:O:h" opt; do
|
46
|
+
case "$opt" in
|
47
|
+
p)
|
48
|
+
PROJECT_DIR="$OPTARG"
|
49
|
+
;;
|
50
|
+
P)
|
51
|
+
PASSENGER_DIR="$OPTARG"
|
52
|
+
;;
|
53
|
+
j)
|
54
|
+
CONCURRENCY="$OPTARG"
|
55
|
+
;;
|
56
|
+
O)
|
57
|
+
EXTRA_ARGS="$OPTARG"
|
58
|
+
;;
|
59
|
+
h)
|
60
|
+
usage
|
61
|
+
exit
|
62
|
+
;;
|
63
|
+
*)
|
64
|
+
return 1
|
65
|
+
;;
|
66
|
+
esac
|
67
|
+
done
|
68
|
+
|
69
|
+
if [[ "$PROJECT_DIR" = "" ]]; then
|
70
|
+
echo "Please specify a project using -p."
|
71
|
+
exit 1
|
72
|
+
fi
|
73
|
+
}
|
74
|
+
|
75
|
+
parse_options "$@"
|
76
|
+
|
77
|
+
if [[ `whoami` != jenkins ]]; then
|
78
|
+
echo "This script may only be run from Jenkins."
|
79
|
+
exit 1
|
80
|
+
fi
|
81
|
+
|
82
|
+
echo "$ cd $SELFROOT"
|
83
|
+
cd "$SELFROOT"
|
84
|
+
|
85
|
+
BUILD_ARGS=(
|
86
|
+
-p "$PROJECT_DIR"
|
87
|
+
-j "$CONCURRENCY"
|
88
|
+
-l
|
89
|
+
$EXTRA_ARGS
|
90
|
+
)
|
91
|
+
if [[ "$PASSENGER_DIR" != "" ]]; then
|
92
|
+
BUILD_ARGS+=(-P "$PASSENGER_DIR")
|
93
|
+
fi
|
94
|
+
|
95
|
+
run ./build "${BUILD_ARGS[@]}"
|
96
|
+
run ./repo_update \
|
97
|
+
-p "$PROJECT_DIR" \
|
98
|
+
-s auto-software-signing@phusion.nl \
|
99
|
+
-x /etc/passenger_rpm_automation/signing_passphrase
|
@@ -0,0 +1,402 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'thread'
|
3
|
+
require 'stringio'
|
4
|
+
require 'singleton'
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/preprocessor')
|
6
|
+
|
7
|
+
MUTEX = Mutex.new
|
8
|
+
SUPPORTED_ARCHS = ['i386', 'x86_64']
|
9
|
+
|
10
|
+
class TrackingDatabase
|
11
|
+
include Singleton
|
12
|
+
|
13
|
+
attr_accessor :thread
|
14
|
+
attr_accessor :category_list
|
15
|
+
attr_reader :start_time
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@category_list = []
|
19
|
+
@categories = {}
|
20
|
+
@start_time = Time.now
|
21
|
+
@finished = false
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_category(name, description)
|
25
|
+
category = TrackingCategory.new(name, description)
|
26
|
+
@category_list << category
|
27
|
+
@categories[name] = category
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](name)
|
31
|
+
@categories[name]
|
32
|
+
end
|
33
|
+
|
34
|
+
def each_category
|
35
|
+
@category_list.each do |category|
|
36
|
+
yield category
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def set_finished!
|
41
|
+
@finished = true
|
42
|
+
end
|
43
|
+
|
44
|
+
def finished?
|
45
|
+
@finished
|
46
|
+
end
|
47
|
+
|
48
|
+
def has_errors?
|
49
|
+
each_category do |category|
|
50
|
+
category.each_task do |task|
|
51
|
+
if task.state == :error
|
52
|
+
return true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
false
|
57
|
+
end
|
58
|
+
|
59
|
+
#### Thread-safe methods ####
|
60
|
+
|
61
|
+
def duration_description
|
62
|
+
distance_of_time_in_hours_and_minutes(@start_time, Time.now)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class TrackingCategory
|
67
|
+
attr_reader :name, :description
|
68
|
+
|
69
|
+
def initialize(name, description)
|
70
|
+
@name = name
|
71
|
+
@description = description
|
72
|
+
@task_list = []
|
73
|
+
@tasks = {}
|
74
|
+
end
|
75
|
+
|
76
|
+
def register_task(name)
|
77
|
+
task = TrackingTask.new(name, self)
|
78
|
+
@task_list << task
|
79
|
+
@tasks[name] = task
|
80
|
+
end
|
81
|
+
|
82
|
+
def [](name)
|
83
|
+
@tasks[name]
|
84
|
+
end
|
85
|
+
|
86
|
+
def each_task
|
87
|
+
@task_list.each do |task|
|
88
|
+
yield task
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
class TrackingTask
|
94
|
+
attr_accessor :state
|
95
|
+
attr_accessor :start_time
|
96
|
+
|
97
|
+
def initialize(name, category)
|
98
|
+
@name = name
|
99
|
+
@category = category
|
100
|
+
@state = :not_started
|
101
|
+
end
|
102
|
+
|
103
|
+
def set_running!
|
104
|
+
@state = :running
|
105
|
+
@start_time = Time.now
|
106
|
+
end
|
107
|
+
|
108
|
+
def set_done!
|
109
|
+
@state = :done
|
110
|
+
@end_time = Time.now
|
111
|
+
end
|
112
|
+
|
113
|
+
def set_error!
|
114
|
+
@state = :error
|
115
|
+
@end_time = Time.now
|
116
|
+
end
|
117
|
+
|
118
|
+
def state_name
|
119
|
+
state.to_s.gsub('_', ' ')
|
120
|
+
end
|
121
|
+
|
122
|
+
def elapsed
|
123
|
+
if @start_time
|
124
|
+
(@end_time || Time.now) - @start_time
|
125
|
+
else
|
126
|
+
nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def duration_description
|
131
|
+
if @start_time
|
132
|
+
distance_of_time_in_hours_and_minutes(@start_time, @end_time || Time.now)
|
133
|
+
else
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
#### Thread-safe methods ####
|
139
|
+
|
140
|
+
attr_reader :name, :category
|
141
|
+
|
142
|
+
def display_name
|
143
|
+
name.to_s.gsub(/[:\.]/, ' ')
|
144
|
+
end
|
145
|
+
|
146
|
+
def sh(command)
|
147
|
+
sh_with_tracking("#{category.name}:#{name}", command)
|
148
|
+
end
|
149
|
+
|
150
|
+
def log(message)
|
151
|
+
track_log("#{category.name}:#{name}", message)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def recursive_copy_files(files, destination_dir, preprocess = false, variables = {})
|
156
|
+
if !STDOUT.tty?
|
157
|
+
puts "Copying files..."
|
158
|
+
end
|
159
|
+
files.each_with_index do |filename, i|
|
160
|
+
dir = File.dirname(filename)
|
161
|
+
if !File.exist?("#{destination_dir}/#{dir}")
|
162
|
+
FileUtils.mkdir_p("#{destination_dir}/#{dir}")
|
163
|
+
end
|
164
|
+
if !File.directory?(filename)
|
165
|
+
if preprocess && filename =~ /\.template$/
|
166
|
+
real_filename = filename.sub(/\.template$/, '')
|
167
|
+
FileUtils.install(filename, "#{destination_dir}/#{real_filename}", :preserve => true)
|
168
|
+
Preprocessor.new.start(filename, "#{destination_dir}/#{real_filename}",
|
169
|
+
variables)
|
170
|
+
else
|
171
|
+
FileUtils.install(filename, "#{destination_dir}/#{filename}", :preserve => true)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
if STDOUT.tty?
|
175
|
+
printf "\r[%5d/%5d] [%3.0f%%] Copying files...", i + 1, files.size, i * 100.0 / files.size
|
176
|
+
STDOUT.flush
|
177
|
+
end
|
178
|
+
end
|
179
|
+
if STDOUT.tty?
|
180
|
+
printf "\r[%5d/%5d] [%3.0f%%] Copying files...\n", files.size, files.size, 100
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def string_option(name, default_value = nil)
|
185
|
+
value = ENV[name]
|
186
|
+
if value.nil? || value.empty?
|
187
|
+
default_value
|
188
|
+
else
|
189
|
+
value
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def boolean_option(name, default_value = false)
|
194
|
+
value = ENV[name]
|
195
|
+
if value.nil? || value.empty?
|
196
|
+
default_value
|
197
|
+
else
|
198
|
+
value == "yes" || value == "on" || value == "true" || value == "1"
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def get_distros_option
|
203
|
+
if distros = string_option('DISTROS')
|
204
|
+
distros.split(/[, ]/)
|
205
|
+
else
|
206
|
+
abort("Please set the DISTROS option.")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def get_archs_option
|
211
|
+
if archs = string_option('ARCHS')
|
212
|
+
archs.split(/[, ]/)
|
213
|
+
else
|
214
|
+
abort("Please set the ARCHS option.")
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def load_passenger
|
219
|
+
if !defined?(PhusionPassenger)
|
220
|
+
require "/passenger/lib/phusion_passenger"
|
221
|
+
PhusionPassenger.locate_directories
|
222
|
+
PhusionPassenger.require_passenger_lib "constants"
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def detect_passenger_version
|
227
|
+
load_passenger
|
228
|
+
PhusionPassenger::VERSION_STRING
|
229
|
+
end
|
230
|
+
|
231
|
+
def detect_nginx_version
|
232
|
+
load_passenger
|
233
|
+
PhusionPassenger::PREFERRED_NGINX_VERSION
|
234
|
+
end
|
235
|
+
|
236
|
+
def enterprise?
|
237
|
+
load_passenger
|
238
|
+
defined?(PhusionPassenger::PASSENGER_IS_ENTERPRISE) &&
|
239
|
+
PhusionPassenger::PASSENGER_IS_ENTERPRISE
|
240
|
+
end
|
241
|
+
|
242
|
+
def initialize_tracking_database!
|
243
|
+
TrackingDatabase.instance
|
244
|
+
TrackingDatabase.instance.thread = Thread.new do
|
245
|
+
Thread.current.abort_on_exception = true
|
246
|
+
while true
|
247
|
+
sleep 5
|
248
|
+
MUTEX.synchronize do
|
249
|
+
dump_tracking_database(false)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def check_distros_supported!
|
256
|
+
DISTROS.each do |distro_id|
|
257
|
+
if !SUPPORTED_DISTROS[distro_id]
|
258
|
+
abort("Unsupported distribution: #{distro_id}. Supported distributions are: #{SUPPORTED_DISTROS.keys.join(' ')}")
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def check_archs_supported!
|
264
|
+
ARCHS.each do |arch|
|
265
|
+
if !SUPPORTED_ARCHS.include?(arch)
|
266
|
+
abort("Unsupported architecture: #{arch}. Supported architectures are: #{SUPPORTED_ARCHS.keys.join(' ')}")
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def clean_bundler_env!
|
272
|
+
clean_env = nil
|
273
|
+
Bundler.with_clean_env do
|
274
|
+
clean_env = ENV.to_hash
|
275
|
+
end
|
276
|
+
ENV.replace(clean_env)
|
277
|
+
end
|
278
|
+
|
279
|
+
def register_tracking_category(name, description)
|
280
|
+
TrackingDatabase.instance.register_category(name, description)
|
281
|
+
end
|
282
|
+
|
283
|
+
def register_tracking_task(category_name, task_name)
|
284
|
+
TrackingDatabase.instance[category_name].register_task(task_name)
|
285
|
+
end
|
286
|
+
|
287
|
+
def track_task(category_name, task_name)
|
288
|
+
succeeded = false
|
289
|
+
task = nil
|
290
|
+
MUTEX.synchronize do
|
291
|
+
category = TrackingDatabase.instance[category_name]
|
292
|
+
task = category[task_name]
|
293
|
+
task.set_running!
|
294
|
+
puts "----- Task started: #{category.description} -> #{task_name} -----"
|
295
|
+
dump_tracking_database
|
296
|
+
end
|
297
|
+
begin
|
298
|
+
yield(task)
|
299
|
+
succeeded = true
|
300
|
+
puts
|
301
|
+
ensure
|
302
|
+
if succeeded
|
303
|
+
task.set_done!
|
304
|
+
puts "----- Task done: #{task.category.description} -> #{task_name} -----"
|
305
|
+
else
|
306
|
+
task.set_error!
|
307
|
+
puts "----- Task errored: #{task.category.description} -> #{task_name} -----"
|
308
|
+
end
|
309
|
+
dump_tracking_database
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def dump_tracking_database(print_to_stdout = true)
|
314
|
+
io = StringIO.new
|
315
|
+
io.puts "Current time: #{format_time(Time.now)}"
|
316
|
+
io.puts "Start time : #{format_time(TrackingDatabase.instance.start_time)}"
|
317
|
+
io.puts "Duration : #{TrackingDatabase.instance.duration_description}"
|
318
|
+
if TrackingDatabase.instance.finished?
|
319
|
+
io.puts "*** FINISHED ***"
|
320
|
+
end
|
321
|
+
if TrackingDatabase.instance.has_errors?
|
322
|
+
io.puts "*** THERE WERE ERRORS ***"
|
323
|
+
end
|
324
|
+
|
325
|
+
io.puts
|
326
|
+
TrackingDatabase.instance.each_category do |category|
|
327
|
+
io.puts "#{category.description}:"
|
328
|
+
category.each_task do |task|
|
329
|
+
io.printf " * %-25s: %-12s\n",
|
330
|
+
task.display_name,
|
331
|
+
task.state_name
|
332
|
+
if task.start_time
|
333
|
+
io.printf " %25s started %s\n", nil, format_time(task.start_time)
|
334
|
+
end
|
335
|
+
if desc = task.duration_description
|
336
|
+
io.printf " %25s duration %s\n", nil, desc
|
337
|
+
end
|
338
|
+
end
|
339
|
+
io.puts
|
340
|
+
end
|
341
|
+
|
342
|
+
if print_to_stdout
|
343
|
+
puts "---------------------------------------------"
|
344
|
+
puts io.string
|
345
|
+
puts "---------------------------------------------"
|
346
|
+
end
|
347
|
+
|
348
|
+
File.open("/output/log/state.log", "w") do |f|
|
349
|
+
f.write(io.string)
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def distance_of_time_in_hours_and_minutes(from_time, to_time)
|
354
|
+
from_time = from_time.to_time if from_time.respond_to?(:to_time)
|
355
|
+
to_time = to_time.to_time if to_time.respond_to?(:to_time)
|
356
|
+
dist = (to_time - from_time).to_i
|
357
|
+
minutes = (dist.abs / 60).round
|
358
|
+
hours = minutes / 60
|
359
|
+
minutes = minutes - (hours * 60)
|
360
|
+
seconds = dist - (hours * 3600) - (minutes * 60)
|
361
|
+
|
362
|
+
words = ''
|
363
|
+
words << "#{hours} #{hours > 1 ? 'hours' : 'hour' } " if hours > 0
|
364
|
+
words << "#{minutes} min " if minutes > 0
|
365
|
+
words << "#{seconds} sec"
|
366
|
+
words
|
367
|
+
end
|
368
|
+
|
369
|
+
def passenger_srpm_name(distro_id)
|
370
|
+
"#{PASSENGER_RPM_NAME}-#{PASSENGER_RPM_VERSION}-#{PASSENGER_RPM_RELEASE}.#{distro_id}.src.rpm"
|
371
|
+
end
|
372
|
+
|
373
|
+
def nginx_srpm_name(distro_id)
|
374
|
+
"#{NGINX_RPM_NAME}-#{NGINX_RPM_VERSION}-#{NGINX_RPM_RELEASE}.#{distro_id}.src.rpm"
|
375
|
+
end
|
376
|
+
|
377
|
+
def format_time(time)
|
378
|
+
time.strftime("%Y-%m-%d %H:%M:%S")
|
379
|
+
end
|
380
|
+
|
381
|
+
def logfile_path_for_tracking_name(name)
|
382
|
+
name = name.gsub(/[: ]/, '.')
|
383
|
+
"/output/log/#{name}.log"
|
384
|
+
end
|
385
|
+
|
386
|
+
def sh_with_tracking(name, command)
|
387
|
+
logfile = logfile_path_for_tracking_name(name)
|
388
|
+
time = format_time(Time.now)
|
389
|
+
puts "#{name}: #{time} -- #{command}"
|
390
|
+
if !system("/system/internal/tracking_helper", name, logfile, "/bin/bash", "-c", command)
|
391
|
+
abort "*** Command failed: #{command}"
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def track_log(name, message)
|
396
|
+
time = format_time(Time.now)
|
397
|
+
message = "#{name}: #{time} -- #{message}"
|
398
|
+
puts message
|
399
|
+
File.open(logfile_path_for_tracking_name(name), "a") do |f|
|
400
|
+
f.puts(message)
|
401
|
+
end
|
402
|
+
end
|