Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/flb_reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,20 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts)

new_config = new_ctx->config;

if (old_config->conf_path) {
new_config->conf_path = flb_strdup(old_config->conf_path);
Comment thread
cosmo0920 marked this conversation as resolved.
if (!new_config->conf_path) {
if (file != NULL) {
flb_sds_destroy(file);
}
flb_cf_destroy(new_cf);
flb_destroy(new_ctx);
flb_error("[reload] copying configuration path failed. Reloading is halted");
flb_reload_watchdog_cleanup(watchdog_ctx);
return FLB_RELOAD_HALTED;
}
}

/* Inherit verbose from the old ctx instance */
verbose = ctx->config->verbose;
new_config->verbose = verbose;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[SERVICE]
Flush 1
Log_Level info
Parsers_File relative-parser.conf
HTTP_Server On
HTTP_Listen 127.0.0.1
HTTP_Port ${FLUENT_BIT_HTTP_MONITORING_PORT}
Hot_Reload On

[INPUT]
Name dummy
Tag relative_parser
Samples 1
Dummy {"message":"after"}

[FILTER]
Name parser
Match relative_parser
Key_Name message
Parser reload_test
Reserve_Data On

[OUTPUT]
Name opentelemetry
Match relative_parser
Host 127.0.0.1
Port ${TEST_SUITE_HTTP_PORT}
Logs_URI /v1/logs
Logs_Body_Key $parsed
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
service:
flush: 1
log_level: info
parsers_file: relative-parser.conf
http_server: on
http_port: ${FLUENT_BIT_HTTP_MONITORING_PORT}
hot_reload: on

pipeline:
inputs:
- name: dummy
tag: relative_parser
samples: 1
dummy: |
{
"message": "after"
}

filters:
- name: parser
match: relative_parser
key_name: message
parser: reload_test
reserve_data: on

outputs:
- name: opentelemetry
match: relative_parser
host: 127.0.0.1
port: ${TEST_SUITE_HTTP_PORT}
logs_uri: /v1/logs
logs_body_key: $parsed
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[SERVICE]
Flush 1
Log_Level info
Parsers_File relative-parser.conf
HTTP_Server On
HTTP_Listen 127.0.0.1
HTTP_Port ${FLUENT_BIT_HTTP_MONITORING_PORT}
Hot_Reload On

[INPUT]
Name dummy
Tag relative_parser
Samples 1
Dummy {"message":"before"}

[FILTER]
Name parser
Match relative_parser
Key_Name message
Parser reload_test
Reserve_Data On

[OUTPUT]
Name opentelemetry
Match relative_parser
Host 127.0.0.1
Port ${TEST_SUITE_HTTP_PORT}
Logs_URI /v1/logs
Logs_Body_Key $parsed
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
service:
flush: 1
log_level: info
parsers_file: relative-parser.conf
http_server: on
http_port: ${FLUENT_BIT_HTTP_MONITORING_PORT}
hot_reload: on

pipeline:
inputs:
- name: dummy
tag: relative_parser
samples: 1
dummy: |
{
"message": "before"
}

filters:
- name: parser
match: relative_parser
key_name: message
parser: reload_test
reserve_data: on

outputs:
- name: opentelemetry
match: relative_parser
host: 127.0.0.1
port: ${TEST_SUITE_HTTP_PORT}
logs_uri: /v1/logs
logs_body_key: $parsed
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[PARSER]
Name reload_test
Format regex
Regex ^(?<parsed>.*)$
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,24 @@


class Service:
def __init__(self, before_name, after_name):
def __init__(self, before_name, after_name, support_files=None):
self.test_path = os.path.dirname(os.path.abspath(__file__))
self.config_dir = os.path.abspath(os.path.join(self.test_path, "../config"))
self.before_config = os.path.join(self.config_dir, before_name)
self.after_config = os.path.join(self.config_dir, after_name)
self.support_files = support_files or []
self.runtime_dir = tempfile.mkdtemp(prefix="flb-hot-reload-watch-")
self.runtime_config = os.path.join(self.runtime_dir, "fluent-bit.yaml")
extension = os.path.splitext(before_name)[1]
self.runtime_config = os.path.join(self.runtime_dir, f"fluent-bit{extension}")
data_storage["logs"] = []

def start(self):
shutil.copyfile(self.before_config, self.runtime_config)
for support_file in self.support_files:
shutil.copyfile(
os.path.join(self.config_dir, support_file),
os.path.join(self.runtime_dir, support_file),
)

self.flb = FluentBitManager(self.runtime_config)
self.test_suite_http_port = find_available_port(starting_port=50000)
Expand Down Expand Up @@ -96,7 +103,7 @@ def read_message(self, index):
return payload["resourceLogs"][0]["scopeLogs"][0]["logRecords"][0]["body"]["stringValue"]

def replace_config(self):
pending_path = os.path.join(self.runtime_dir, "fluent-bit.yaml.tmp")
pending_path = f"{self.runtime_config}.tmp"
shutil.copyfile(self.after_config, pending_path)
os.replace(pending_path, self.runtime_config)

Expand Down Expand Up @@ -178,3 +185,37 @@ def test_hot_reload_http_yaml_config_change():
assert_reload_result(service)
finally:
service.stop()


@pytest.mark.parametrize(
("before_name", "after_name"),
[
("fluent-bit-relative-parser-before.conf", "fluent-bit-relative-parser-after.conf"),
("fluent-bit-relative-parser-before.yaml", "fluent-bit-relative-parser-after.yaml"),
],
ids=["classic", "yaml"],
)
def test_hot_reload_http_relative_parser(before_name, after_name):
parser_file = "relative-parser.conf"

# Ensure the parser cannot be loaded relative to the process working directory.
assert not os.path.exists(os.path.join(os.getcwd(), parser_file))

service = Service(before_name, after_name, support_files=[parser_file])

try:
service.start()
service.wait_for_log_count(1)
assert service.read_message(0) == "before"

service.replace_config()

with pytest.raises(TimeoutError):
service.flb.wait_for_hot_reload_count(1, timeout=2)

payload = service.flb.trigger_http_reload()
assert payload["reload"] == "done"
service.flb.wait_for_hot_reload_count(1)
assert_reload_result(service)
finally:
service.stop()
1 change: 1 addition & 0 deletions tests/internal/data/reload/fluent-bit.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Flush 1
Daemon Off
Log_Level error
Parsers_File parsers.conf
HTTP_Server On
HTTP_Listen 0.0.0.0
HTTP_Port 2022
Expand Down
3 changes: 3 additions & 0 deletions tests/internal/data/reload/parsers.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[PARSER]
Name reload_test
Format json
9 changes: 9 additions & 0 deletions tests/internal/reload.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <fluent-bit/flb_kv.h>
#include <fluent-bit/flb_config_format.h>
#include <fluent-bit/flb_lib.h>
#include <fluent-bit/flb_parser.h>
#include <fluent-bit/flb_reload.h>

#include <cfl/cfl.h>
Expand All @@ -22,6 +23,7 @@
#define FLB_YAML FLB_TESTS_DATA_PATH "/data/reload/yaml/processor.yaml"
#define FLB_YAML_MISSING_INCLUDE FLB_TESTS_DATA_PATH "/data/reload/yaml/missing_include.yaml"
#define FLB_CLASSIC FLB_TESTS_DATA_PATH "/data/reload/fluent-bit.conf"
#define FLB_CLASSIC_PATH FLB_TESTS_DATA_PATH "/data/reload/"

void test_reconstruct_cf()
{
Expand Down Expand Up @@ -147,11 +149,14 @@ void test_reload()
cf = flb_cf_create_from_file(cf, FLB_CLASSIC);
TEST_CHECK(cf != NULL);

ctx->config->conf_path = flb_strdup(FLB_CLASSIC_PATH);
TEST_CHECK(ctx->config->conf_path != NULL);
ctx->config->conf_path_file = flb_sds_create(FLB_CLASSIC);
ctx->config->enable_hot_reload = FLB_TRUE;

status = flb_config_load_config_format(ctx->config, cf);
TEST_CHECK(status == 0);
TEST_CHECK(flb_parser_get("reload_test", ctx->config) != NULL);

/* Start the engine */
status = flb_start(ctx);
Expand All @@ -162,12 +167,16 @@ void test_reload()

status = flb_reload(ctx, cf_opts);
TEST_CHECK(status == 0);
TEST_MSG("Expected reload status 0, got %d", status);

sleep(2);

/* flb context should be replaced with flb_reload() */
ctx = flb_context_get();

TEST_CHECK(ctx->config->conf_path != NULL &&
strcmp(ctx->config->conf_path, FLB_CLASSIC_PATH) == 0);
TEST_CHECK(flb_parser_get("reload_test", ctx->config) != NULL);
TEST_CHECK(mk_list_size(&ctx->config->cf_opts->inputs) == 1);
TEST_CHECK(mk_list_size(&ctx->config->inputs) == 2);

Expand Down
Loading