Skip to content

Commit

Permalink
Set Default Target
Browse files Browse the repository at this point in the history
Added Api to set the default target

Signed-off-by: Artiom Divak <[email protected]>
  • Loading branch information
ArtiomDivak committed Oct 1, 2024
1 parent ee6a46c commit 339c140
Show file tree
Hide file tree
Showing 14 changed files with 190 additions and 42 deletions.
18 changes: 16 additions & 2 deletions data/org.eclipse.bluechi.Node.xml
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,29 @@
</method>

<!--
DefaultTarget:
GetDefaultTarget:
@defaulttarget the default target.
Get the default value of the system to boot into.
@defaulttarget the default target.
-->
<method name="GetDefaultTarget">
<arg name="defaulttarget" type="s" direction="out" />
</method>

<!--
SetDefaultTarget:
@defaulttarget the default target.
@force bollean value of force.
@out the result of the method.
Set the default value of the system to boot into.
-->
<method name="SetDefaultTarget">
<arg name="defaulttarget" type="s" direction="in" />
<arg name="force" type="b" direction="in" />
<arg name="out" type="a(sss)" direction="out" />
</method>

<!--
Name:
Expand Down
5 changes: 5 additions & 0 deletions data/org.eclipse.bluechi.internal.Agent.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,11 @@
<method name="GetDefaultTarget">
<arg name="defaulttarget" type="s" direction="out" />
</method>
<method name="SetDefaultTarget">
<arg name="defaulttarget" type="s" direction="in" />
<arg name="force" type="b" direction="in" />
<arg name="out" type="a(sss)" direction="out" />
</method>

<signal name="JobDone">
<arg name="id" type="u" />
Expand Down
2 changes: 1 addition & 1 deletion src/agent/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -1758,7 +1758,6 @@ static int agent_method_job_cancel(sd_bus_message *m, void *userdata, UNUSED sd_
return sd_bus_reply_method_return(m, "");
}


static const sd_bus_vtable internal_agent_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_METHOD("ListUnits", "", UNIT_INFO_STRUCT_ARRAY_TYPESTRING, agent_method_list_units, 0),
Expand Down Expand Up @@ -1787,6 +1786,7 @@ static const sd_bus_vtable internal_agent_vtable[] = {
SD_BUS_METHOD("StartDep", "s", "", agent_method_start_dep, 0),
SD_BUS_METHOD("StopDep", "s", "", agent_method_stop_dep, 0),
SD_BUS_METHOD("GetDefaultTarget", "", "s", agent_method_passthrough_to_systemd, 0),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", agent_method_passthrough_to_systemd, 0),
SD_BUS_SIGNAL_WITH_NAMES("JobDone", "us", SD_BUS_PARAM(id) SD_BUS_PARAM(result), 0),
SD_BUS_SIGNAL_WITH_NAMES("JobStateChanged", "us", SD_BUS_PARAM(id) SD_BUS_PARAM(state), 0),
SD_BUS_SIGNAL_WITH_NAMES(
Expand Down
2 changes: 2 additions & 0 deletions src/client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "method-metrics.h"
#include "method-monitor.h"
#include "method-reset-failed.h"
#include "method-set-default-target.h"
#include "method-status.h"
#include "method-unit-lifecycle.h"

Expand Down Expand Up @@ -61,6 +62,7 @@ const Method methods[] = {
{ "status", 0, ARG_ANY, OPT_WATCH, method_status, usage_method_status },
{ "set-loglevel", 1, 2, OPT_NONE, method_set_loglevel, usage_method_set_loglevel },
{ "get-default", 1, 1, OPT_NONE, method_get_default_target, usage_method_get_default_target },
{ "set-default", 3, 3, OPT_NONE, method_set_default_target, usage_method_set_default_target },
{ "version", 0, 0, OPT_NONE, method_version, usage_bluechi },
{ NULL, 0, 0, 0, NULL, NULL }
};
Expand Down
1 change: 1 addition & 0 deletions src/client/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ client_src = [
'method-reset-failed.c',
'method-daemon-reload.c',
'method-get-default-target.c',
'method-set-default-target.c',
'usage.c',
]

Expand Down
1 change: 0 additions & 1 deletion src/client/method-get-default-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ static int method_get_default_target_on(Client *client, char *node_name) {

void usage_method_get_default_target() {
usage_print_header();
usage_print_description("Start/Stop/Restart/Reload a unit on a node");
usage_print_usage("bluechictl get-default [nodename]");
}

Expand Down
4 changes: 3 additions & 1 deletion src/client/method-help.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ void usage_bluechi() {
printf(" - set-loglevel: change the log level of the bluechi-controller or a connected node\n");
printf(" usage: set-loglevel [nodename] [loglevel]\n");
printf(" - get-default: get a default target of connected node\n");
printf(" usage: get-dafault [nodename]\n");
printf(" usage: get-default [nodename]\n");
printf(" - set-default: set a default target of connected node\n");
printf(" usage: set-default [nodename] [target] [force]\n");
}

int method_help(UNUSED Command *command, UNUSED void *userdata) {
Expand Down
85 changes: 85 additions & 0 deletions src/client/method-set-default-target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright Contributors to the Eclipse BlueChi project
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#include "method-set-default-target.h"
#include "client.h"
#include "usage.h"

#include "libbluechi/common/opt.h"

static int method_set_default_target_on(Client *client, char *node_name, char *target, char *force) {
_cleanup_sd_bus_error_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_sd_bus_message_ sd_bus_message *message = NULL;
int r = 0;
bool force_b = 0;
if (!strcmp(force, "true")) {
force_b = 1;
} else if (!strcmp(force, "false")) {
force_b = 0;
} else {
fprintf(stderr, "Please provide a true/false value for force parameter\n");
return -1;
}


r = assemble_object_path_string(NODE_OBJECT_PATH_PREFIX, node_name, &client->object_path);
if (r < 0) {
return r;
}

r = sd_bus_call_method(
client->api_bus,
BC_INTERFACE_BASE_NAME,
client->object_path,
NODE_INTERFACE,
"SetDefaultTarget",
&error,
&message,
"sb",
target,
force_b);
if (r < 0) {
fprintf(stderr, "Failed to issue method call: %s\n", error.message);
return r;
}

r = sd_bus_message_enter_container(message, SD_BUS_TYPE_ARRAY, "(sss)");
if (r < 0) {
fprintf(stderr, "Failed to open the strings array container: %s\n", strerror(-r));
return r;
}
printf("[");
for (;;) {
const char *result1 = NULL;
const char *result2 = NULL;
const char *result3 = NULL;

r = sd_bus_message_read(message, "(sss)", &result1, &result2, &result3);
if (r < 0) {
fprintf(stderr, "Failed to read the SetDefaultTarget response: %s\n", strerror(-r));
return r;
}
if (r == 0) {
break;
}
printf("(%s %s %s),", result1, result2, result3);
}
printf("]\n");

printf("The default target of node %s is now: %s\n", node_name, target);

return r;
}

void usage_method_set_default_target() {
usage_print_header();
usage_print_usage("bluechictl set-default [nodename]");
}


int method_set_default_target(Command *command, void *userdata) {
return method_set_default_target_on(
userdata, command->opargv[0], command->opargv[1], command->opargv[2]);
}
11 changes: 11 additions & 0 deletions src/client/method-set-default-target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright Contributors to the Eclipse BlueChi project
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
#pragma once

#include "libbluechi/cli/command.h"

int method_set_default_target(Command *command, void *userdata);
void usage_method_set_default_target();
39 changes: 2 additions & 37 deletions src/controller/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ static int node_method_restart_unit(sd_bus_message *m, void *userdata, UNUSED sd
static int node_method_reload_unit(sd_bus_message *m, void *userdata, UNUSED sd_bus_error *ret_error);
static int node_method_passthrough_to_agent(sd_bus_message *m, void *userdata, UNUSED sd_bus_error *ret_error);
static int node_method_set_log_level(sd_bus_message *m, void *userdata, UNUSED sd_bus_error *ret_error);
static int node_method_get_default_target(sd_bus_message *m, void *userdata, UNUSED sd_bus_error *ret_error);
static int node_property_get_status(
sd_bus *bus,
const char *path,
Expand Down Expand Up @@ -87,7 +86,8 @@ static const sd_bus_vtable node_vtable[] = {
SD_BUS_METHOD("Reload", "", "", node_method_passthrough_to_agent, 0),
SD_BUS_METHOD("KillUnit", "ssi", "", node_method_passthrough_to_agent, 0),
SD_BUS_METHOD("SetLogLevel", "s", "", node_method_set_log_level, 0),
SD_BUS_METHOD("GetDefaultTarget", "", "s", node_method_get_default_target, 0),
SD_BUS_METHOD("GetDefaultTarget", "", "s", node_method_passthrough_to_agent, 0),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", node_method_passthrough_to_agent, 0),
SD_BUS_PROPERTY("Name", "s", NULL, offsetof(Node, name), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Status", "s", node_property_get_status, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
SD_BUS_PROPERTY("PeerIp", "s", node_property_get_peer_ip, 0, SD_BUS_VTABLE_PROPERTY_EXPLICIT),
Expand Down Expand Up @@ -1688,41 +1688,6 @@ static int node_method_set_log_level(sd_bus_message *m, UNUSED void *userdata, U
}
return sd_bus_reply_method_return(m, "");
}
/*************************************************************************
********** org.eclipse.bluechi.Node.GetDefaultTarget *******************
************************************************************************/

static int node_method_get_default_target(UNUSED sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
Node *node = (Node *) userdata;
_cleanup_sd_bus_message_ sd_bus_message *empty = NULL;
_cleanup_sd_bus_message_ sd_bus_message *reply = NULL;
int r = sd_bus_message_new_method_call(
node->agent_bus,
&empty,
BC_AGENT_DBUS_NAME,
INTERNAL_AGENT_OBJECT_PATH,
INTERNAL_AGENT_INTERFACE,
"GetDefaultTarget");
if (r < 0) {
fprintf(stderr, "Failed creating new method call: %s\n", strerror(-r));
return r;
}

r = sd_bus_call(node->agent_bus, empty, BC_DEFAULT_DBUS_TIMEOUT, ret_error, &reply);
if (r < 0) {
fprintf(stderr, "Failed to call method: %s\n", strerror(-r));
return r;
}

const char *default_target = NULL;
r = sd_bus_message_read(reply, "s", &default_target);
if (r < 0) {
fprintf(stderr, "Failed reading the mesaage: %s\n", strerror(-r));
return r;
}

return sd_bus_reply_method_return(m, "s", default_target);
}

static int send_agent_simple_message(Node *node, const char *method, const char *arg) {
_cleanup_sd_bus_message_ sd_bus_message *m = NULL;
Expand Down
16 changes: 16 additions & 0 deletions tests/bluechi_test/bluechictl.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,22 @@ def get_default_target(
check_result,
expected_result,
)

def set_default_target(
self,
node_name: str = "",
target: str = "",
force: str = "false",
check_result: bool = True,
expected_result: int = 0,
) -> Tuple[Optional[int], Union[Iterator[bytes], Any, Tuple[bytes, bytes]]]:
cmd = f"set-default {node_name} {target} {force}".strip()
return self._run(
f"SetDefaultTarget of node {node_name} ",
cmd,
check_result,
expected_result,
)

def kill_unit(
self,
Expand Down
2 changes: 2 additions & 0 deletions tests/tests/tier0/bluechi-set-default-target/main.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
summary: Test the set default target function
id: 6cfa53b6-7429-43fd-a9b5-ff59e98b7408
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#
# Copyright Contributors to the Eclipse BlueChi project
#
# SPDX-License-Identifier: LGPL-2.1-or-later

from typing import Dict

from bluechi_test.config import BluechiAgentConfig, BluechiControllerConfig
from bluechi_test.machine import BluechiAgentMachine, BluechiControllerMachine
from bluechi_test.test import BluechiTest

NODE_FOO = "node-foo"


def exec(ctrl: BluechiControllerMachine, nodes: Dict[str, BluechiAgentMachine]):
node_foo = nodes[NODE_FOO]
multi_user_string = "multi-user.target"
graphical_string = "graphical.target"

_, systemd_result = node_foo.exec_run("systemctl get-default")

if systemd_result == multi_user_string:
ctrl.bluechictl.set_default_target(NODE_FOO, graphical_string, "false")
_, systemd_result = node_foo.exec_run("systemctl get-default")
assert systemd_result == graphical_string
else:
ctrl.bluechictl.set_default_target(NODE_FOO, multi_user_string, "false")
_, systemd_result = node_foo.exec_run("systemctl get-default")
assert systemd_result == multi_user_string


def test_bluechi_set_default_target(
bluechi_test: BluechiTest,
bluechi_node_default_config: BluechiAgentConfig,
bluechi_ctrl_default_config: BluechiControllerConfig,
):

node_foo_cfg = bluechi_node_default_config.deep_copy()
node_foo_cfg.node_name = NODE_FOO

bluechi_ctrl_default_config.allowed_node_names = [NODE_FOO]
bluechi_test.set_bluechi_controller_config(bluechi_ctrl_default_config)

bluechi_test.add_bluechi_agent_config(node_foo_cfg)

bluechi_test.run(exec)

0 comments on commit 339c140

Please sign in to comment.