Skip to content

Commit

Permalink
Added Fatal Action extension point. (envoyproxy#13676)
Browse files Browse the repository at this point in the history
Signed-off-by: Kevin Baichoo <[email protected]>
  • Loading branch information
KBaichoo authored Nov 18, 2020
1 parent ce3fe2e commit 6e5227e
Show file tree
Hide file tree
Showing 30 changed files with 823 additions and 20 deletions.
27 changes: 22 additions & 5 deletions REPO_LAYOUT.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,8 @@ Not every directory within test is described below, but a few highlights:
## [source/extensions](source/extensions/) layout

We maintain a very specific code and namespace layout for extensions. This aids in discovering
code/extensions, and also will allow us in the future to more easily scale out our extension
maintainers by having OWNERS files specific to certain extensions. (As of this writing, this is not
currently implemented but that is the plan moving forward.)
code/extensions, and allows us specify extension owners in [CODEOWNERS](CODEOWNERS).


* All extensions are either registered in [all_extensions.bzl](source/extensions/all_extensions.bzl)
or [extensions_build_config.bzl](source/extensions/extensions_build_config.bzl). The former is
Expand All @@ -76,6 +75,14 @@ currently implemented but that is the plan moving forward.)
* These are the top level extension directories and associated namespaces:
* [access_loggers/](/source/extensions/access_loggers): Access log implementations which use
the `Envoy::Extensions::AccessLoggers` namespace.
* [bootstrap](/source/extensions/bootstrap): Bootstrap extensions which use
the `Envoy::Extensions::Bootstrap` namespace.
* [clusters](/source/extensions/clusters): Cluster extensions which use the
`Envoy::Extensions::Clusters` namespace.
* [compression](/source/extensions/compression): Compression extensions
which use `Envoy::Extensions::Compression` namespace.
* [fatal_actions](/source/extensions/fatal_actions): Fatal Action extensions
which use the `Envoy::Extensions::FatalActions` namespace.
* [filters/http/](/source/extensions/filters/http): HTTP L7 filters which use the
`Envoy::Extensions::HttpFilters` namespace.
* [filters/listener/](/source/extensions/filters/listener): Listener filters which use the
Expand All @@ -86,14 +93,24 @@ currently implemented but that is the plan moving forward.)
`Envoy::Extensions::GrpcCredentials` namespace.
* [health_checker/](/source/extensions/health_checker): Custom health checkers which use the
`Envoy::Extensions::HealthCheckers` namespace.
* [resolvers/](/source/extensions/resolvers): Network address resolvers which use the
`Envoy::Extensions::Resolvers` namespace.
* [internal_redirect](/source/extensions/internal_redirect): Internal Redirect
extensions which use the `Envoy::Extensions::InternalRedirect` namespace.
* [quic_listeners](/source/extensions/quic_listeners): QUIC extensions which
use the `Envoy::Quic` namespace.
* [resource_monitors](/source/extensions/resource_monitors): Resource monitor
extensions which use the `Envoy::Extensions::ResourceMonitors` namespace.
* [retry](/source/extensions/retry): Retry extensions which use the
`Envoy::Extensions::Retry` namespace.
* [stat_sinks/](/source/extensions/stat_sinks): Stat sink implementations which use the
`Envoy::Extensions::StatSinks` namespace.
* [tracers/](/source/extensions/tracers): Tracers which use the
`Envoy::Extensions::Tracers` namespace.
* [transport_sockets/](/source/extensions/transport_sockets): Transport socket implementations
which use the `Envoy::Extensions::TransportSockets` namespace.
* [upstreams](/source/extensions/upstreams): Upstream extensions use the
`Envoy::Extensions::Upstreams` namespace.
* [watchdog](/source/extensions/watchdog): Watchdog extensions use the
`Envoy::Extensions::Watchdog` namespace.
* Each extension is contained wholly in its own namespace. E.g.,
`Envoy::Extensions::NetworkFilters::Echo`.
* Common code that is used by multiple extensions should be in a `common/` directory as close to
Expand Down
20 changes: 19 additions & 1 deletion api/envoy/config/bootstrap/v3/bootstrap.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// <config_overview_bootstrap>` for more detail.

// Bootstrap :ref:`configuration overview <config_overview_bootstrap>`.
// [#next-free-field: 28]
// [#next-free-field: 29]
message Bootstrap {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.bootstrap.v2.Bootstrap";
Expand Down Expand Up @@ -243,6 +243,10 @@ message Bootstrap {
// Each item contains extension specific configuration.
repeated core.v3.TypedExtensionConfig bootstrap_extensions = 21;

// Specifies optional extensions instantiated at startup time and
// invoked during crash time on the request that caused the crash.
repeated FatalAction fatal_actions = 28;

// Configuration sources that will participate in
// *udpa.core.v1.ResourceLocator* authority resolution. The algorithm is as
// follows:
Expand Down Expand Up @@ -420,6 +424,20 @@ message Watchdog {
type.v3.Percent multikill_threshold = 5;
}

// Fatal actions to run while crashing. Actions can be safe (meaning they are
// async-signal safe) or unsafe. We run all safe actions before we run unsafe actions.
// If using an unsafe action that could get stuck or deadlock, it important to
// have an out of band system to terminate the process.
//
// The interface for the extension is ``Envoy::Server::Configuration::FatalAction``.
// *FatalAction* extensions live in the ``envoy.extensions.fatal_actions`` API
// namespace.
message FatalAction {
// Extension specific configuration for the action. It's expected to conform
// to the ``Envoy::Server::Configuration::FatalAction`` interface.
core.v3.TypedExtensionConfig config = 1;
}

// Runtime :ref:`configuration overview <config_runtime>` (deprecated).
message Runtime {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.bootstrap.v2.Runtime";
Expand Down
23 changes: 22 additions & 1 deletion api/envoy/config/bootstrap/v4alpha/bootstrap.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions docs/root/extending/extending.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ types including:
* :ref:`Watchdog action <envoy_v3_api_msg_config.bootstrap.v3.Watchdog.WatchdogAction>`
* :ref:`Internal redirect policy <envoy_v3_api_field_config.route.v3.InternalRedirectPolicy.predicates>`
* :ref:`Compression libraries <arch_overview_compression_libraries>`
* :ref:`Bootstrap extensions <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.bootstrap_extensions>`
* :ref:`Fatal actions <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.fatal_actions>`

As of this writing there is no high level extension developer documentation. The
:repo:`existing extensions <source/extensions>` are a good way to learn what is possible.
Expand Down
1 change: 1 addition & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ New Features
* sds: improved support for atomic :ref:`key rotations <xds_certificate_rotation>` and added configurable rotation triggers for
:ref:`TlsCertificate <envoy_v3_api_field_extensions.transport_sockets.tls.v3.TlsCertificate.watched_directory>` and
:ref:`CertificateValidationContext <envoy_v3_api_field_extensions.transport_sockets.tls.v3.CertificateValidationContext.watched_directory>`.
* signal: added an extension point for custom actions to run on the thread that has encountered a fatal error. Actions are configurable via :ref:`fatal_actions <envoy_v3_api_field_config.bootstrap.v3.Bootstrap.fatal_actions>`.
* tcp: added a new :ref:`envoy.overload_actions.reject_incoming_connections <config_overload_manager_overload_actions>` action to reject incoming TCP connections.
* tls: added support for RSA certificates with 4096-bit keys in FIPS mode.
* tracing: added SkyWalking tracer.
Expand Down
20 changes: 19 additions & 1 deletion generated_api_shadow/envoy/config/bootstrap/v3/bootstrap.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions include/envoy/server/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -329,3 +329,15 @@ envoy_cc_library(
"//include/envoy/config:typed_config_interface",
],
)

envoy_cc_library(
name = "fatal_action_interface",
hdrs = ["fatal_action_config.h"],
deps = [
"//include/envoy/config:typed_config_interface",
"//include/envoy/event:dispatcher_interface",
"//include/envoy/protobuf:message_validator_interface",
"//include/envoy/server:instance_interface",
"@envoy_api//envoy/config/bootstrap/v3:pkg_cc_proto",
],
)
59 changes: 59 additions & 0 deletions include/envoy/server/fatal_action_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <memory>

#include "envoy/common/pure.h"
#include "envoy/config/bootstrap/v3/bootstrap.pb.h"
#include "envoy/config/typed_config.h"
#include "envoy/event/dispatcher.h"
#include "envoy/protobuf/message_validator.h"
#include "envoy/server/instance.h"

namespace Envoy {
namespace Server {
namespace Configuration {

class FatalAction {
public:
virtual ~FatalAction() = default;
/**
* Callback function to run when we are crashing.
* @param current_object the object we were working on when we started
* crashing.
*/
virtual void run(const ScopeTrackedObject* current_object) PURE;

/**
* @return whether the action is async-signal-safe.
* See man 7 signal-safety for the definition of async-signal-safe.
*/
virtual bool isAsyncSignalSafe() const PURE;
};

using FatalActionPtr = std::unique_ptr<FatalAction>;

/**
* Implemented by each custom FatalAction and registered via Registry::registerFactory()
* or the convenience class RegisterFactory.
*/
class FatalActionFactory : public Config::TypedFactory {
public:
~FatalActionFactory() override = default;

/**
* Creates a particular FatalAction implementation.
*
* @param config supplies the configuration for the action.
* @param context supplies the GuardDog Action's context.
* @return FatalActionsPtr the FatalActions object.
*/
virtual FatalActionPtr
createFatalActionFromProto(const envoy::config::bootstrap::v3::FatalAction& config,
Instance* server) PURE;

std::string category() const override { return "envoy.fatal_action"; }
};

} // namespace Configuration
} // namespace Server
} // namespace Envoy
13 changes: 13 additions & 0 deletions source/common/event/dispatcher_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,19 @@ void DispatcherImpl::runPostCallbacks() {
}
}

void DispatcherImpl::runFatalActionsOnTrackedObject(
const FatalAction::FatalActionPtrList& actions) const {
// Only run if this is the dispatcher of the current thread and
// DispatcherImpl::Run has been called.
if (run_tid_.isEmpty() || (run_tid_ != api_.threadFactory().currentThreadId())) {
return;
}

for (const auto& action : actions) {
action->run(current_object_);
}
}

void DispatcherImpl::touchWatchdog() {
if (watchdog_registration_) {
watchdog_registration_->touchWatchdog();
Expand Down
3 changes: 3 additions & 0 deletions source/common/event/dispatcher_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ class DispatcherImpl : Logger::Loggable<Logger::Id::main>,
}
}

void
runFatalActionsOnTrackedObject(const FatalAction::FatalActionPtrList& actions) const override;

private:
// Holds a reference to the watchdog registered with this dispatcher and the timer used to ensure
// that the dog is touched periodically.
Expand Down
11 changes: 11 additions & 0 deletions source/common/signal/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ envoy_cc_library(
srcs = ["fatal_error_handler.cc"],
hdrs = ["fatal_error_handler.h"],
deps = [
":fatal_action_lib",
"//include/envoy/event:dispatcher_interface",
"//source/common/common:macros",
],
)
Expand All @@ -30,3 +32,12 @@ envoy_cc_library(
"//source/server:backtrace_lib",
],
)

envoy_cc_library(
name = "fatal_action_lib",
hdrs = ["fatal_action.h"],
deps = [
"//include/envoy/server:fatal_action_interface",
"//include/envoy/thread:thread_interface",
],
)
Loading

0 comments on commit 6e5227e

Please sign in to comment.