Skip to content

Commit

Permalink
dinit-service: Do parameter substitution in consumer-of
Browse files Browse the repository at this point in the history
Seems useful for s6-log/vlogger based logging systems.

Signed-off-by: Mobin Aydinfar <[email protected]>
  • Loading branch information
mobin-2008 committed Feb 10, 2025
1 parent f349b88 commit 7bebbc4
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 2 deletions.
2 changes: 2 additions & 0 deletions doc/manpages/dinit-service.5.m4
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,8 @@ Specifies that this service consumes (as its standard input) the output of anoth
For example, this allows this service to act as a logging agent for another service.
The named service must be a process-based service with \fBlog\-type\fR set to \fBpipe\fR.
This setting is only valid for \fBprocess\fR and \fBbgprocess\fR services.
The \fIservice-name\fR is subject to pre-load variable substitution
(see \fBVARIABLE SUBSTITUTION\fR).
.TP
\fBoptions\fR: \fIoption\fR...
Specifies various options for this service. See the \fBOPTIONS\fR section.
Expand Down
47 changes: 46 additions & 1 deletion src/igr-tests/igr-runner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void offline_enable_test();
void xdg_config_test();
void cycles_test();
void svc_arg_test();
void svc_arg_consumer_test();

int main(int argc, char **argv)
{
Expand All @@ -57,7 +58,7 @@ int main(int argc, char **argv)
{ "before-after2", before_after2_test }, { "log-via-pipe", log_via_pipe_test },
{ "catlog", catlog_test }, { "offline-enable", offline_enable_test },
{ "xdg-config", xdg_config_test }, { "cycles", cycles_test },
{ "svc-arg", svc_arg_test } };
{ "svc-arg", svc_arg_test }, { "svc-arg-consumer", svc_arg_consumer_test } };
constexpr int num_tests = sizeof(tests) / sizeof(tests[0]);

dinit_bindir = "../..";
Expand Down Expand Up @@ -998,3 +999,47 @@ void svc_arg_test()
"foo\n" +
"bar\n");
}

void svc_arg_consumer_test()
{
// Test for using minimal variable substitution in consumer services
igr_test_setup setup("svc-arg-consumer");

std::string logged_output_file = setup.prep_output_file("logged-output");
std::string socket_path = setup.prep_socket_path();

// "boot" service brings up "consumer" service and consumer writes its $1 value
dinit_proc dinit_p;
dinit_p.start("svc-arg-consumer", {"-u", "-d", "sd", "-p", socket_path, "-q"}, true);

nanosleepx(0, 1000000000u / 10u);

igr_assert_eq(read_file_contents(logged_output_file), "producer\n");

// Start and stop the producer for printing output to consumer
dinitctl_proc dinitctl_p;
dinitctl_p.start("svc-arg-consumer", {"-u", "-p", socket_path, "start", "producer"});
int status = dinitctl_p.wait_for_term({1, 0}); /* max 1 second */
igr_assert(status == 0, "dinitctl did not exit cleanly");

dinitctl_p.start("svc-arg-consumer", {"-u", "-p", socket_path, "stop", "producer"});
status = dinitctl_p.wait_for_term({1, 0}); /* max 1 second */
igr_assert(status == 0, "dinitctl did not exit cleanly");

nanosleepx(0, (1000000000u / 10u) * 2u);

igr_assert_eq(read_file_contents(logged_output_file), "producer\n" "Producing output...\n");

// Another start and stop to make sure that producer is linked to consumer properly
dinitctl_p.start("svc-arg-consumer", {"-u", "-p", socket_path, "start", "producer"});
status = dinitctl_p.wait_for_term({1, 0}); /* max 1 second */
igr_assert(status == 0, "dinitctl did not exit cleanly");

dinitctl_p.start("svc-arg-consumer", {"-u", "-p", socket_path, "stop", "producer"});
status = dinitctl_p.wait_for_term({1, 0}); /* max 1 second */
igr_assert(status == 0, "dinitctl did not exit cleanly");

nanosleepx(0, (1000000000u / 10u) * 2u);

igr_assert_eq(read_file_contents(logged_output_file), "producer\n" "Producing output...\n" "Producing output...\n");
}
3 changes: 3 additions & 0 deletions src/igr-tests/svc-arg-consumer/scripts/consumer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
echo "$1" > "$IGR_OUTPUT/logged-output"
cat - >> "$IGR_OUTPUT/logged-output" 2>&1
2 changes: 2 additions & 0 deletions src/igr-tests/svc-arg-consumer/scripts/producer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
echo "Producing output..."
2 changes: 2 additions & 0 deletions src/igr-tests/svc-arg-consumer/sd/boot
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
type = internal
waits-for = consumer@producer
3 changes: 3 additions & 0 deletions src/igr-tests/svc-arg-consumer/sd/consumer
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type = process
command = ../scripts/consumer.sh $1
consumer-of = $1
3 changes: 3 additions & 0 deletions src/igr-tests/svc-arg-consumer/sd/producer
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type = scripted
command = ../scripts/producer.sh
log-type = pipe
3 changes: 2 additions & 1 deletion src/includes/load-service.h
Original file line number Diff line number Diff line change
Expand Up @@ -1946,7 +1946,8 @@ void process_service_line(settings_wrapper &settings, const char *name, const ch
}
case setting_id_t::CONSUMER_OF:
{
string consumed_svc_name = read_setting_value(input_pos, i, end);
string consumed_svc_name = read_value_resolved(setting.c_str(), input_pos, i, end,
service_arg, lookup_var);
if (consumed_svc_name == name) {
throw service_description_exc(name, "service cannot be its own consumer", "consumer-of",
input_pos);
Expand Down

0 comments on commit 7bebbc4

Please sign in to comment.