From cfdc4198b5e965ece177bb1358f654de2d0078c1 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Wed, 14 Aug 2013 15:06:04 +0200 Subject: [PATCH] After Passenger Standalone downloads binaries, check whether they're usable --- ext/common/agents/HelperAgent/AgentOptions.h | 6 +++ ext/common/agents/HelperAgent/Main.cpp | 5 +++ ext/common/agents/LoggingAgent/Main.cpp | 4 ++ ext/common/agents/Watchdog/Main.cpp | 5 +++ .../standalone/runtime_installer.rb | 27 +++++++++++- .../ruby/standalone/runtime_installer_spec.rb | 43 +++++++++++++++---- 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/ext/common/agents/HelperAgent/AgentOptions.h b/ext/common/agents/HelperAgent/AgentOptions.h index dd779e0ae8..7a95e5845f 100644 --- a/ext/common/agents/HelperAgent/AgentOptions.h +++ b/ext/common/agents/HelperAgent/AgentOptions.h @@ -56,11 +56,17 @@ struct AgentOptions { string adminToolStatusPassword; vector prestartUrls; + bool testBinary; string requestSocketLink; AgentOptions() { } AgentOptions(const VariantMap &options) { + testBinary = options.get("test_binary", false) == "1"; + if (testBinary) { + return; + } + // Required options for which a default is already set by the Watchdog. passengerRoot = options.get("passenger_root"); tempDir = options.get("temp_dir"); diff --git a/ext/common/agents/HelperAgent/Main.cpp b/ext/common/agents/HelperAgent/Main.cpp index 79f72638cc..153605bcba 100644 --- a/ext/common/agents/HelperAgent/Main.cpp +++ b/ext/common/agents/HelperAgent/Main.cpp @@ -587,6 +587,11 @@ int main(int argc, char *argv[]) { TRACE_POINT(); AgentOptions options(initializeAgent(argc, argv, "PassengerHelperAgent")); + if (options.testBinary) { + printf("PASS\n"); + exit(0); + } + P_DEBUG("Starting PassengerHelperAgent..."); MultiLibeio::init(); diff --git a/ext/common/agents/LoggingAgent/Main.cpp b/ext/common/agents/LoggingAgent/Main.cpp index d693450df3..41503b093d 100644 --- a/ext/common/agents/LoggingAgent/Main.cpp +++ b/ext/common/agents/LoggingAgent/Main.cpp @@ -126,6 +126,10 @@ static void initializeBareEssentials(int argc, char *argv[]) { agentsOptions = initializeAgent(argc, argv, "PassengerLoggingAgent"); curl_global_init(CURL_GLOBAL_ALL); + if (agentsOptions.get("test_binary", false) == "1") { + printf("PASS\n"); + exit(0); + } } static string diff --git a/ext/common/agents/Watchdog/Main.cpp b/ext/common/agents/Watchdog/Main.cpp index 9dc80a233b..c4282f2ea4 100644 --- a/ext/common/agents/Watchdog/Main.cpp +++ b/ext/common/agents/Watchdog/Main.cpp @@ -413,6 +413,11 @@ initializeBareEssentials(int argc, char *argv[]) { oldOomScore = setOomScoreNeverKill(); agentsOptions = initializeAgent(argc, argv, "PassengerWatchdog"); + + if (agentsOptions.get("test_binary", false) == "1") { + printf("PASS\n"); + exit(0); + } } static void diff --git a/lib/phusion_passenger/standalone/runtime_installer.rb b/lib/phusion_passenger/standalone/runtime_installer.rb index b200e9ec76..10a14e6686 100644 --- a/lib/phusion_passenger/standalone/runtime_installer.rb +++ b/lib/phusion_passenger/standalone/runtime_installer.rb @@ -243,7 +243,19 @@ def download_support_binaries FileUtils.mkdir_p(@support_dir) Dir.chdir(@support_dir) do puts "Extracting tarball..." - return extract_tarball(tarball) + result = extract_tarball(tarball) + return nil if !result + + puts "Checking whether the downloaded binary is usable..." + ["PassengerWatchdog", "PassengerHelperAgent", "PassengerLoggingAgent"].each do |exe| + output = `env LD_BIND_NOW=1 DYLD_BIND_AT_LAUNCH=1 ./agents/#{exe} --binary-test 1` + if !$? || $?.exitstatus != 0 || output != "PASS\n" + puts "Binary #{exe} is not usable." + return nil + end + end + puts "Binary is usable." + return result end rescue Interrupt exit 2 @@ -266,7 +278,18 @@ def download_nginx_binary FileUtils.mkdir_p(@nginx_dir) Dir.chdir(@nginx_dir) do puts "Extracting tarball..." - return extract_tarball(tarball) + result = extract_tarball(tarball) + return nil if !result + + puts "Checking whether the downloaded binary is usable..." + output = `env LD_BIND_NOW=1 DYLD_BIND_AT_LAUNCH=1 ./nginx -h` + if $? && $?.exitstatus == 0 && output =~ /nginx version:/ + puts "Binary is usable." + return result + else + puts "Binary is not usable." + return nil + end end rescue Interrupt exit 2 diff --git a/test/ruby/standalone/runtime_installer_spec.rb b/test/ruby/standalone/runtime_installer_spec.rb index b4311c617f..970f8e0dfe 100644 --- a/test/ruby/standalone/runtime_installer_spec.rb +++ b/test/ruby/standalone/runtime_installer_spec.rb @@ -52,6 +52,25 @@ def create_tarball(filename, contents = nil) end end + def create_dummy_support_binaries + Dir.mkdir("agents") + ["PassengerWatchdog", "PassengerHelperAgent", "PassengerLoggingAgent"].each do |exe| + File.open("agents/#{exe}", "w") do |f| + f.puts "#!/bin/bash" + f.puts "echo PASS" + end + File.chmod(0755, "agents/#{exe}") + end + end + + def create_dummy_nginx_binary + File.open("nginx", "w") do |f| + f.puts "#!/bin/bash" + f.puts "echo nginx version: 1.0.0" + end + File.chmod(0755, "nginx") + end + def create_file(filename) File.open(filename, "w").close end @@ -71,7 +90,9 @@ def test_download_nginx_binary and_return do |url, output, options| url.should == nginx_binary_url options[:use_cache].should be_true - create_tarball(output, ["nginx.txt"]) + create_tarball(output) do + create_dummy_nginx_binary + end true end @@ -82,7 +103,7 @@ def test_download_nginx_binary @installer.should_not_receive(:compile_nginx) @installer.run - File.exist?("#{@temp_dir}/nginx/nginx.txt").should be_true + File.exist?("#{@temp_dir}/nginx/nginx").should be_true end def test_building_nginx_binary @@ -139,7 +160,9 @@ def test_building_nginx_binary and_return do |url, output, options| url.should == "#{binaries_url_root}/#{version}/support-#{cxx_compat_id}.tar.gz" options[:use_cache].should be_true - create_tarball(output, ["support.txt"]) + create_tarball(output) do + create_dummy_support_binaries + end true end @@ -150,7 +173,7 @@ def test_building_nginx_binary @installer.should_not_receive(:compile_nginx) @installer.run - File.exist?("#{@temp_dir}/support/support.txt").should be_true + File.exist?("#{@temp_dir}/support/agents/PassengerWatchdog").should be_true end it "downloads the Nginx binary from the Internet if :nginx is specified as target" do @@ -167,9 +190,13 @@ def test_building_nginx_binary twice. and_return do |url, output, options| if url == support_binaries_url - create_tarball(output, ["support.txt"]) + create_tarball(output) do + create_dummy_support_binaries + end elsif url == nginx_binary_url - create_tarball(output, ["nginx.txt"]) + create_tarball(output) do + create_dummy_nginx_binary + end else raise "Unexpected download URL: #{url}" end @@ -184,8 +211,8 @@ def test_building_nginx_binary @installer.should_not_receive(:compile_nginx) @installer.run - File.exist?("#{@temp_dir}/support/support.txt").should be_true - File.exist?("#{@temp_dir}/nginx/nginx.txt").should be_true + File.exist?("#{@temp_dir}/support/agents/PassengerWatchdog").should be_true + File.exist?("#{@temp_dir}/nginx/nginx").should be_true end it "builds the support binaries if it cannot be downloaded" do