diff options
-rw-r--r-- | client/CMakeLists.txt | 1 | ||||
-rw-r--r-- | client/go/script-utils/main.go | 2 | ||||
-rw-r--r-- | container-test/pom.xml | 2 | ||||
-rw-r--r-- | controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java | 3 | ||||
-rw-r--r-- | controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java | 3 | ||||
-rw-r--r-- | parent/pom.xml | 2 | ||||
-rw-r--r-- | searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp | 238 | ||||
-rw-r--r-- | security-tools/CMakeLists.txt | 2 | ||||
-rw-r--r-- | security-tools/README.md | 2 | ||||
-rwxr-xr-x | security-tools/src/main/sh/vespa-security-env | 81 | ||||
-rw-r--r-- | vespalog/src/logger/runserver.cpp | 14 |
11 files changed, 209 insertions, 141 deletions
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index ad4c1524644..2507215e70d 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -15,6 +15,7 @@ install(PROGRAMS ${GODIR}/bin/script-utils DESTINATION libexec/vespa) install_symlink(libexec/vespa/script-utils bin/vespa-logfmt) install_symlink(libexec/vespa/script-utils bin/vespa-deploy) +install_symlink(libexec/vespa/script-utils bin/vespa-security-env) install_symlink(libexec/vespa/script-utils bin/vespa-get-cluster-state) install_symlink(libexec/vespa/script-utils bin/vespa-get-node-state) install_symlink(libexec/vespa/script-utils bin/vespa-set-node-state) diff --git a/client/go/script-utils/main.go b/client/go/script-utils/main.go index a27e94a76a7..3be527cdf0c 100644 --- a/client/go/script-utils/main.go +++ b/client/go/script-utils/main.go @@ -34,7 +34,7 @@ func main() { os.Exit(startcbinary.Run(os.Args[1:])) case "export-env": vespa.ExportDefaultEnvToSh() - case "security-env": + case "security-env", "vespa-security-env": vespa.ExportSecurityEnvToSh() case "ipv6-only": if vespa.HasOnlyIpV6() { diff --git a/container-test/pom.xml b/container-test/pom.xml index ed33c0ba4cd..32a64a98b9e 100644 --- a/container-test/pom.xml +++ b/container-test/pom.xml @@ -100,7 +100,7 @@ <artifactId>commons-compress</artifactId> <scope>compile</scope> </dependency> - <dependency> + <dependency> <!-- TODO: Remove on Vespa 9 --> <!-- not used by Vespa, but was historically on test classpath --> <groupId>org.json</groupId> <artifactId>json</artifactId> diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java index 0fe9a84f5fa..c09fff19d58 100644 --- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java +++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentStatus.java @@ -378,7 +378,8 @@ public class DeploymentStatus { /** The set of jobs that need to run for the given changes to be considered complete. */ public boolean hasCompleted(InstanceName instance, Change change) { - if ( ! application.deploymentSpec().requireInstance(instance).concerns(prod)) { + DeploymentInstanceSpec spec = application.deploymentSpec().requireInstance(instance); + if ((spec.concerns(test) || spec.concerns(staging)) && ! spec.concerns(prod)) { if (newestTested(instance, run -> run.versions().targetRevision()).map(change::downgrades).orElse(false)) return true; if (newestTested(instance, run -> run.versions().targetPlatform()).map(change::downgrades).orElse(false)) return true; } diff --git a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java index 6d1e5cebe0e..d9726edc496 100644 --- a/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java +++ b/controller-server/src/test/java/com/yahoo/vespa/hosted/controller/deployment/DeploymentTriggerTest.java @@ -1291,6 +1291,9 @@ public class DeploymentTriggerTest { String complicatedDeploymentSpec = """ <deployment version='1.0' athenz-domain='domain' athenz-service='service'> + <instance id='dev'> + <dev /> + </instance> <parallel> <instance id='instance' athenz-service='in-service'> <staging /> diff --git a/parent/pom.xml b/parent/pom.xml index b019db32e93..62d57660bcf 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -994,7 +994,7 @@ <artifactId>xercesImpl</artifactId> <version>2.12.2</version> </dependency> - <dependency> + <dependency> <!-- TODO: Remove on Vespa 9 --> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>${org.json.version}</version> diff --git a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp index 5741d210079..ecb7ee3b48b 100644 --- a/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp +++ b/searchlib/src/tests/queryeval/filter_search/filter_search_test.cpp @@ -5,14 +5,25 @@ #include <vespa/searchlib/queryeval/intermediate_blueprints.h> #include <vespa/searchlib/queryeval/leaf_blueprints.h> #include <vespa/searchlib/queryeval/isourceselector.h> +#include <vespa/searchlib/queryeval/simple_phrase_blueprint.h> +#include <vespa/searchlib/queryeval/equiv_blueprint.h> +#include <vespa/searchlib/queryeval/weighted_set_term_blueprint.h> +#include <vespa/searchlib/queryeval/dot_product_blueprint.h> +#include <vespa/searchlib/queryeval/same_element_blueprint.h> +#include <vespa/searchlib/queryeval/wand/parallel_weak_and_blueprint.h> +#include <vespa/searchlib/fef/matchdatalayout.h> #include <vespa/vespalib/util/trinary.h> #include <vespa/vespalib/util/require.h> #include <vespa/vespalib/gtest/gtest.h> #include <functional> +namespace search::fef { class TermFieldMatchDataArray; } namespace search::fef { class MatchData; } using namespace search::queryeval; +using search::fef::MatchData; +using search::fef::MatchDataLayout; +using search::fef::TermFieldMatchDataArray; using vespalib::Trinary; using Constraint = Blueprint::FilterConstraint; @@ -28,7 +39,12 @@ concept FilterFactory = requires(const T &a, bool strict, Constraint upper_or_lo template <typename T> concept FilterFactoryBuilder = requires(T a, std::unique_ptr<Blueprint> bp) { - { std::move(a).add(std::move(bp)) } -> std::same_as<T&&>; + { a.add(std::move(bp)) } -> std::same_as<T&>; +}; + +template <typename T> +concept ChildCollector = requires(T a, std::unique_ptr<Blueprint> bp) { + a.addChild(std::move(bp)); }; // inherit Blueprint to capture the default filter factory @@ -37,7 +53,22 @@ struct DefaultBlueprint : Blueprint { const State &getState() const override { abort(); } void fetchPostings(const ExecuteInfo &) override { abort(); } void freeze() override { abort(); } - SearchIteratorUP createSearch(search::fef::MatchData &, bool) const override { abort(); } + SearchIteratorUP createSearch(MatchData &, bool) const override { abort(); } +}; + +// add the use of a field to a leaf blueprint (SimplePhraseBlueprint asserts on this) +struct FakeFieldProxy : SimpleLeafBlueprint { + std::unique_ptr<Blueprint> child; + FakeFieldProxy(const FieldSpec &field, std::unique_ptr<Blueprint> child_in) + : SimpleLeafBlueprint(field), child(std::move(child_in)) + { + setParent(child->getParent()); + child->setParent(this); + } + SearchIteratorUP createLeafSearch(const TermFieldMatchDataArray &, bool) const override { abort(); } + SearchIteratorUP createFilterSearch(bool strict, Constraint upper_or_lower) const override { + return child->createFilterSearch(strict, upper_or_lower); + } }; // need one of these to be able to create a SourceBlender @@ -48,7 +79,6 @@ struct NullSelector : ISourceSelector { void compactLidSpace(uint32_t) override { abort(); } std::unique_ptr<sourceselector::Iterator> createIterator() const override { abort(); } }; -NullSelector null_selector; // make a simple result containing the given documents SimpleResult make_result(const std::vector<uint32_t> &docs) { @@ -84,7 +114,7 @@ std::unique_ptr<Blueprint> full() { } // create a leaf blueprint with the specified hits -std::unique_ptr<Blueprint> leaf(const std::vector<uint32_t> &docs) { +std::unique_ptr<Blueprint> hits(const std::vector<uint32_t> &docs) { return std::make_unique<SimpleBlueprint>(make_result(docs)); } @@ -95,24 +125,24 @@ struct Children { std::vector<Factory> list; Children() : list() {} size_t size() const { return list.size(); } - Children &&leaf(const std::vector<uint32_t> &docs) && { - list.push_back([docs](){ return ::leaf(docs); }); - return std::move(*this); + Children &hits(const std::vector<uint32_t> &docs) { + list.push_back([docs](){ return ::hits(docs); }); + return *this; } - Children &&full() && { + Children &full() { list.push_back([](){ return ::full(); }); - return std::move(*this); + return *this; } - Children &&empty() && { + Children &empty() { list.push_back([](){ return ::empty(); }); - return std::move(*this); + return *this; } template <FilterFactoryBuilder Builder> - Builder &&apply(Builder &&builder) const { + Builder &apply(Builder &builder) const { for (const Factory &make_child: list) { - std::move(builder).add(make_child()); + builder.add(make_child()); } - return std::move(builder); + return builder; } }; @@ -123,12 +153,12 @@ struct Combine { factory_fun fun; Blueprint::Children list; Combine(factory_fun fun_in) noexcept : fun(fun_in), list() {} - Combine &&add(std::unique_ptr<Blueprint> child) && { + Combine &add(std::unique_ptr<Blueprint> child) { list.push_back(std::move(child)); - return std::move(*this); + return *this; } - Combine &&add(const Children &children) && { - return children.apply(std::move(*this)); + Combine &add(const Children &children) { + return children.apply(*this); } auto createFilterSearch(bool strict, Constraint upper_or_lower) const { return fun(list, strict, upper_or_lower); @@ -137,19 +167,118 @@ struct Combine { }; Combine::~Combine() = default; -// Make a specific (intermediate) blueprint that you can add children -// to. Satisfies the FilterFactory concept. +// enable Make-ing source blender +struct SourceBlenderAdapter { + NullSelector selector; + SourceBlenderBlueprint blueprint; + SourceBlenderAdapter() : selector(), blueprint(selector) {} + void addChild(std::unique_ptr<Blueprint> child) { + blueprint.addChild(std::move(child)); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// enable Make-ing simple phrase +struct SimplePhraseAdapter { + FieldSpec field; + SimplePhraseBlueprint blueprint; + SimplePhraseAdapter() : field("foo", 3, 7), blueprint(field, false) {} + void addChild(std::unique_ptr<Blueprint> child) { + auto child_field = blueprint.getNextChildField(field); + auto term = std::make_unique<FakeFieldProxy>(child_field, std::move(child)); + blueprint.addTerm(std::move(term)); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +//enable Make-ing equiv +struct EquivAdapter { + FieldSpecBaseList fields; + EquivBlueprint blueprint; + EquivAdapter() : fields(), blueprint(fields, MatchDataLayout()) {} + void addChild(std::unique_ptr<Blueprint> child) { + blueprint.addTerm(std::move(child), 1.0); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// enable Make-ing weighted set +struct WeightedSetTermAdapter { + FieldSpec field; + WeightedSetTermBlueprint blueprint; + WeightedSetTermAdapter() : field("foo", 3, 7), blueprint(field) {} + void addChild(std::unique_ptr<Blueprint> child) { + blueprint.addTerm(std::move(child), 100); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// enable Make-ing dot product +struct DotProductAdapter { + FieldSpec field; + DotProductBlueprint blueprint; + DotProductAdapter() : field("foo", 3, 7), blueprint(field) {} + void addChild(std::unique_ptr<Blueprint> child) { + auto child_field = blueprint.getNextChildField(field); + auto term = std::make_unique<FakeFieldProxy>(child_field, std::move(child)); + blueprint.addTerm(std::move(term), 100); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// enable Make-ing parallel weak and +struct ParallelWeakAndAdapter { + FieldSpec field; + ParallelWeakAndBlueprint blueprint; + ParallelWeakAndAdapter() : field("foo", 3, 7), blueprint(field, 100, 0.0, 1.0) {} + void addChild(std::unique_ptr<Blueprint> child) { + auto child_field = blueprint.getNextChildField(field); + auto term = std::make_unique<FakeFieldProxy>(child_field, std::move(child)); + blueprint.addTerm(std::move(term), 100); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// enable Make-ing same element +struct SameElementAdapter { + SameElementBlueprint blueprint; + SameElementAdapter() : blueprint("foo", false) {} + void addChild(std::unique_ptr<Blueprint> child) { + auto child_field = blueprint.getNextChildField("foo", 3); + auto term = std::make_unique<FakeFieldProxy>(child_field, std::move(child)); + blueprint.addTerm(std::move(term)); + } + auto createFilterSearch(bool strict, Constraint upper_or_lower) const { + return blueprint.createFilterSearch(strict, upper_or_lower); + } +}; + +// Make a specific intermediate-ish blueprint that you can add +// children to. Satisfies the FilterFactory concept. template <FilterFactory T> +requires ChildCollector<T> struct Make { T blueprint; template <typename ... Args> Make(Args && ... args) : blueprint(std::forward<Args>(args)...) {} - Make &&add(std::unique_ptr<Blueprint> child) && { + Make &add(std::unique_ptr<Blueprint> child) { blueprint.addChild(std::move(child)); - return std::move(*this); + return *this; } - Make &&add(const Children &children) && { - return children.apply(std::move(*this)); + Make &add(const Children &children) { + return children.apply(*this); } auto createFilterSearch(bool strict, Constraint upper_or_lower) const { return blueprint.createFilterSearch(strict, upper_or_lower); @@ -159,19 +288,20 @@ struct Make { // what kind of results are we expecting from a filter search? struct Expect { Trinary matches_any; - SimpleResult hits; - Expect(const std::vector<uint32_t> &hits_in) - : matches_any(Trinary::Undefined), hits(make_result(hits_in)) {} - Expect(Trinary matches_any_in) : matches_any(matches_any_in), hits() { + SimpleResult docs; + Expect(const std::vector<uint32_t> &docs_in) + : matches_any(Trinary::Undefined), docs(make_result(docs_in)) {} + Expect(Trinary matches_any_in) : matches_any(matches_any_in), docs() { REQUIRE(matches_any != Trinary::Undefined); if (matches_any == Trinary::True) { - hits = make_full_result(); + docs = make_full_result(); } else { - hits = make_empty_result(); + docs = make_empty_result(); } } static Expect empty() { return Expect(Trinary::False); } static Expect full() { return Expect(Trinary::True); } + static Expect hits(const std::vector<uint32_t> &docs) { return Expect(docs); } }; template <FilterFactory Blueprint> @@ -187,7 +317,7 @@ void verify(const Blueprint &blueprint, const Expect &upper, const Expect &lower } else { actual.search(*filter, docid_limit); } - EXPECT_EQ(actual, expect.hits); + EXPECT_EQ(actual, expect.docs); } } } @@ -206,7 +336,7 @@ TEST(FilterSearchTest, full_leaf) { } TEST(FilterSearchTest, custom_leaf) { - verify(*leaf({5,10,20}), Expect({5,10,20})); + verify(*hits({5,10,20}), Expect::hits({5,10,20})); } TEST(FilterSearchTest, default_blueprint) { @@ -215,48 +345,54 @@ TEST(FilterSearchTest, default_blueprint) { TEST(FilterSearchTest, simple_or) { auto child_list = Children() - .leaf({5, 10}) - .leaf({7}) - .leaf({3, 11}); - auto expected = Expect({3, 5, 7, 10, 11}); + .hits({5, 10}) + .hits({7}) + .hits({3, 11}); + auto expected = Expect::hits({3, 5, 7, 10, 11}); verify(Combine(Blueprint::create_or_filter).add(child_list), expected); verify(Make<OrBlueprint>().add(child_list), expected); + verify(Make<EquivAdapter>().add(child_list), expected); + verify(Make<WeightedSetTermAdapter>().add(child_list), expected); + verify(Make<DotProductAdapter>().add(child_list), expected); verify(Combine(Blueprint::create_atmost_or_filter).add(child_list), expected, Expect::empty()); - verify(Make<WeakAndBlueprint>(child_list.size()).add(child_list), expected, Expect::empty()); - verify(Make<SourceBlenderBlueprint>(null_selector).add(child_list), expected, Expect::empty()); + verify(Make<WeakAndBlueprint>(100).add(child_list), expected, Expect::empty()); + verify(Make<SourceBlenderAdapter>().add(child_list), expected, Expect::empty()); + verify(Make<ParallelWeakAndAdapter>().add(child_list), expected, Expect::empty()); } TEST(FilterSearchTest, simple_and) { auto child_list = Children() - .leaf({1, 2, 3, 4, 5, 6}) - .leaf({2, 4, 6, 7}) - .leaf({1, 4, 6, 7, 10}); - auto expected = Expect({4, 6}); + .hits({1, 2, 3, 4, 5, 6}) + .hits({2, 4, 6, 7}) + .hits({1, 4, 6, 7, 10}); + auto expected = Expect::hits({4, 6}); verify(Combine(Blueprint::create_and_filter).add(child_list), expected); verify(Make<AndBlueprint>().add(child_list), expected); verify(Combine(Blueprint::create_atmost_and_filter).add(child_list), expected, Expect::empty()); verify(Make<NearBlueprint>(3).add(child_list), expected, Expect::empty()); verify(Make<ONearBlueprint>(3).add(child_list), expected, Expect::empty()); + verify(Make<SimplePhraseAdapter>().add(child_list), expected, Expect::empty()); + verify(Make<SameElementAdapter>().add(child_list), expected, Expect::empty()); } TEST(FilterSearchTest, simple_andnot) { auto child_list = Children() - .leaf({1, 2, 3, 4, 5, 6}) - .leaf({2, 4, 6}) - .leaf({4, 6, 7}); - auto expected = Expect({1, 3, 5}); + .hits({1, 2, 3, 4, 5, 6}) + .hits({2, 4, 6}) + .hits({4, 6, 7}); + auto expected = Expect::hits({1, 3, 5}); verify(Combine(Blueprint::create_andnot_filter).add(child_list), expected); verify(Make<AndNotBlueprint>().add(child_list), expected); } TEST(FilterSearchTest, rank_filter) { - auto child_list1 = Children().leaf({1,2,3}).empty().full(); - auto child_list2 = Children().empty().leaf({1,2,3}).full(); - auto child_list3 = Children().full().leaf({1,2,3}).empty(); - verify(Combine(Blueprint::create_first_child_filter).add(child_list1), Expect({1,2,3})); + auto child_list1 = Children().hits({1,2,3}).empty().full(); + auto child_list2 = Children().empty().hits({1,2,3}).full(); + auto child_list3 = Children().full().hits({1,2,3}).empty(); + verify(Combine(Blueprint::create_first_child_filter).add(child_list1), Expect::hits({1,2,3})); verify(Combine(Blueprint::create_first_child_filter).add(child_list2), Expect::empty()); verify(Combine(Blueprint::create_first_child_filter).add(child_list3), Expect::full()); - verify(Make<RankBlueprint>().add(child_list1), Expect({1,2,3})); + verify(Make<RankBlueprint>().add(child_list1), Expect::hits({1,2,3})); verify(Make<RankBlueprint>().add(child_list2), Expect::empty()); verify(Make<RankBlueprint>().add(child_list3), Expect::full()); } diff --git a/security-tools/CMakeLists.txt b/security-tools/CMakeLists.txt index 8341f57b9cc..cc85473f758 100644 --- a/security-tools/CMakeLists.txt +++ b/security-tools/CMakeLists.txt @@ -1,6 +1,4 @@ # Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. install_jar(security-tools-jar-with-dependencies.jar) -vespa_install_script(src/main/sh/vespa-security-env vespa-security-env bin) vespa_install_script(src/main/sh/vespa-curl-wrapper vespa-curl-wrapper libexec/vespa) - diff --git a/security-tools/README.md b/security-tools/README.md index 3dc33c7a86c..a5267e88fc2 100644 --- a/security-tools/README.md +++ b/security-tools/README.md @@ -1,4 +1,2 @@ <!-- Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> # security-tools - -Contains the "vespa-security-env" command line tool for Vespa. diff --git a/security-tools/src/main/sh/vespa-security-env b/security-tools/src/main/sh/vespa-security-env deleted file mode 100755 index b8f972653d6..00000000000 --- a/security-tools/src/main/sh/vespa-security-env +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env bash -# Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -# BEGIN environment bootstrap section -# Do not edit between here and END as this section should stay identical in all scripts - -findpath () { - myname=${0} - mypath=${myname%/*} - myname=${myname##*/} - empty_if_start_slash=${mypath%%/*} - if [ "${empty_if_start_slash}" ]; then - mypath=$(pwd)/${mypath} - fi - if [ "$mypath" ] && [ -d "$mypath" ]; then - return - fi - mypath=$(pwd) - if [ -f "${mypath}/${myname}" ]; then - return - fi - echo "FATAL: Could not figure out the path where $myname lives from $0" - exit 1 -} - -COMMON_ENV=libexec/vespa/common-env.sh - -source_common_env () { - if [ "$VESPA_HOME" ] && [ -d "$VESPA_HOME" ]; then - export VESPA_HOME - common_env=$VESPA_HOME/$COMMON_ENV - if [ -f "$common_env" ]; then - . $common_env - return - fi - fi - return 1 -} - -findroot () { - source_common_env && return - if [ "$VESPA_HOME" ]; then - echo "FATAL: bad VESPA_HOME value '$VESPA_HOME'" - exit 1 - fi - if [ "$ROOT" ] && [ -d "$ROOT" ]; then - VESPA_HOME="$ROOT" - source_common_env && return - fi - findpath - while [ "$mypath" ]; do - VESPA_HOME=${mypath} - source_common_env && return - mypath=${mypath%/*} - done - echo "FATAL: missing VESPA_HOME environment variable" - echo "Could not locate $COMMON_ENV anywhere" - exit 1 -} - -findhost () { - if [ "${VESPA_HOSTNAME}" = "" ]; then - VESPA_HOSTNAME=$(vespa-detect-hostname || hostname -f || hostname || echo "localhost") || exit 1 - fi - validate="${VESPA_HOME}/bin/vespa-validate-hostname" - if [ -f "$validate" ]; then - "$validate" "${VESPA_HOSTNAME}" || exit 1 - fi - export VESPA_HOSTNAME -} - -findroot -findhost - -ROOT=${VESPA_HOME%/} -export ROOT - -# END environment bootstrap section - -exec java -Djava.awt.headless=true -cp ${VESPA_HOME}/lib/jars/security-tools-jar-with-dependencies.jar com.yahoo.vespa.security.tool.securityenv.Main "$@" - diff --git a/vespalog/src/logger/runserver.cpp b/vespalog/src/logger/runserver.cpp index f9dde87ca14..7cec2be6f3f 100644 --- a/vespalog/src/logger/runserver.cpp +++ b/vespalog/src/logger/runserver.cpp @@ -342,6 +342,7 @@ int usage(char *prog, int es) int main(int argc, char *argv[]) { bool doStop = false; + bool checkWouldRun = false; int restart = 0; const char *service = "runserver"; const char *pidfile = "vespa-runserver.pid"; // XXX bad default? @@ -350,7 +351,7 @@ int main(int argc, char *argv[]) signal(SIGQUIT, SIG_IGN); int ch; - while ((ch = getopt(argc, argv, "k:s:r:p:Sh")) != -1) { + while ((ch = getopt(argc, argv, "k:s:r:p:ShW")) != -1) { switch (ch) { case 's': service = optarg; @@ -367,6 +368,9 @@ int main(int argc, char *argv[]) case 'k': killcmd = optarg; break; + case 'W': + checkWouldRun = true; + break; default: return usage(argv[0], ch != 'h'); } @@ -383,6 +387,14 @@ int main(int argc, char *argv[]) } PidFile mypf(pidfile); + if (checkWouldRun) { + if (mypf.anotherRunning()) { + fprintf(stderr, "%s already running with pid %d\n", service, mypf.readPid()); + return 1; + } else { + return 0; + } + } if (doStop) { if (mypf.anotherRunning()) { int pid = mypf.readPid(); |