• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eclipse-bluechi / bluechi / 12348609570

16 Dec 2024 08:22AM UTC coverage: 82.356% (+1.4%) from 80.974%
12348609570

Pull #1008

github

web-flow
Merge 2e5a15ef6 into de238ccae
Pull Request #1008: Add integration test for bluechi-is-online agent with --wait parameter

5480 of 6654 relevant lines covered (82.36%)

1110.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

77.22
/src/proxy/main.c
1
/*
2
 * Copyright Contributors to the Eclipse BlueChi project
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 */
6
#include <errno.h>
7
#include <getopt.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <string.h>
11

12
#include "libbluechi/bus/bus.h"
13
#include "libbluechi/common/common.h"
14
#include "libbluechi/common/opt.h"
15
#include "libbluechi/log/log.h"
16

17
const struct option options[] = {
18
        { ARG_USER,    no_argument, 0, ARG_USER_SHORT    },
19
        { ARG_HELP,    no_argument, 0, ARG_HELP_SHORT    },
20
        { ARG_VERSION, no_argument, 0, ARG_VERSION_SHORT },
21
        { NULL,        0,           0, '\0'              }
22
};
23

24
#define GETOPT_OPTSTRING ARG_HELP_SHORT_S ARG_USER_SHORT_S ARG_VERSION_SHORT_S
25

26
static const char *opt_node_unit = NULL;
27
static const char *opt_operation = NULL;
28
static bool opt_user = false;
29

30
#ifdef USE_USER_API_BUS
31
#        define ALWAYS_USER_API_BUS 1
32
#else
33
#        define ALWAYS_USER_API_BUS 0
34
#endif
35

36
#define OPT_OPERATION_CREATE "create"
37
#define OPT_OPERATION_REMOVE "remove"
38

39
static void usage(char *argv[]) {
4✔
40
        printf("Usage: %s \n"
4✔
41
               "\t[-h help]\t\t Print this help message.\n"
42
               "\t<operation>\t\t Required. Operation to perform. Must be one of [%s,%s].\n"
43
               "\t<node>_<service>\t Required. Input the name of the node the required service is supposed to run on.\n"
44
               "\t<[-v version]\t Print current version of bluechi-proxy\n",
45
               argv[0],
46
               OPT_OPERATION_CREATE,
47
               OPT_OPERATION_REMOVE);
48
}
4✔
49

50
int parse_node_unit_opt(const char *opt_node_unit, char **ret_node_name, char **ret_unit_name) {
21✔
51
        if (opt_node_unit == NULL || ret_node_name == NULL || ret_unit_name == NULL) {
21✔
52
                return -EINVAL;
53
        }
54

55
        char *split = strchr(opt_node_unit, '_');
21✔
56
        if (split == NULL || split == opt_node_unit) {
21✔
57
                fprintf(stderr, "No underscore in unit name '%s'\n", opt_node_unit);
×
58
                return -EINVAL;
×
59
        }
60
        if (split[1] == 0) {
21✔
61
                fprintf(stderr, "No service specified in unit name '%s'\n", opt_node_unit);
×
62
                return -EINVAL;
×
63
        }
64

65
        *ret_node_name = strndup(opt_node_unit, split - opt_node_unit);
21✔
66
        *ret_unit_name = strdup(split + 1);
21✔
67

68
        if (*ret_node_name == NULL || *ret_unit_name == NULL) {
21✔
69
                fprintf(stderr, "Out of memory\n");
×
70
                return -ENOMEM;
×
71
        }
72

73
        return 0;
74
}
75

76
static int get_opts(int argc, char *argv[]) {
27✔
77
        int opt = 0;
27✔
78
        while ((opt = getopt_long(argc, argv, GETOPT_OPTSTRING, options, NULL)) != -1) {
27✔
79
                switch (opt) {
6✔
80
                case ARG_HELP_SHORT:
2✔
81
                        usage(argv);
2✔
82
                        return 1;
2✔
83

84
                case ARG_VERSION_SHORT:
85
                        printf("bluechi-proxy version %s\n", CONFIG_H_BC_VERSION);
2✔
86
                        return 1;
2✔
87

88
                case ARG_USER_SHORT:
×
89
                        opt_user = true;
×
90
                        break;
×
91
                default:
2✔
92
                        fprintf(stderr, "Unsupported option %c\n", opt);
2✔
93
                        usage(argv);
2✔
94
                        return -EINVAL;
2✔
95
                }
96
        }
97

98
        if (argc < 3) {
21✔
99
                fprintf(stderr, "Not enough arguments specified\n");
×
100
                return -EINVAL;
×
101
        }
102
        opt_operation = argv[optind];
21✔
103
        opt_node_unit = argv[optind + 1];
21✔
104

105
        if (!streqi(opt_operation, OPT_OPERATION_CREATE) && !streqi(opt_operation, OPT_OPERATION_REMOVE)) {
21✔
106
                fprintf(stderr, "Unsupported command %s\n", opt_operation);
×
107
                return -EINVAL;
×
108
        }
109

110
        return 0;
111
}
112

113

114
static int call_proxy_method(
21✔
115
                sd_bus *api_bus,
116
                const char *method,
117
                const char *service_name,
118
                const char *node_name,
119
                const char *unit_name) {
120
        _cleanup_sd_bus_error_ sd_bus_error error = SD_BUS_ERROR_NULL;
×
121
        _cleanup_sd_bus_message_ sd_bus_message *message = NULL;
21✔
122
        _cleanup_free_ char *proxy_service = strcat_dup("bluechi-proxy@", service_name);
42✔
123

124
        int r = sd_bus_call_method(
21✔
125
                        api_bus,
126
                        BC_AGENT_DBUS_NAME,
127
                        BC_AGENT_OBJECT_PATH,
128
                        AGENT_INTERFACE,
129
                        method,
130
                        &error,
131
                        &message,
132
                        "sss",
133
                        proxy_service,
134
                        node_name,
135
                        unit_name);
136
        if (r < 0) {
21✔
137
                if (streq(error.name, BC_BUS_ERROR_ACTIVATION_FAILED)) {
3✔
138
                        fprintf(stderr,
3✔
139
                                "Failed to activate %s (on %s): %s\n",
140
                                proxy_service,
141
                                node_name,
142
                                error.message);
143
                } else {
144
                        fprintf(stderr, "Failed to call %s: %s\n", method, error.message);
×
145
                }
146
                return r;
3✔
147
        }
148
        return 0;
149
}
150

151
int main(int argc, char *argv[]) {
27✔
152
        bc_log_set_quiet(false);
27✔
153
        bc_log_set_level(LOG_LEVEL_INFO);
27✔
154
        bc_log_set_log_fn(bc_log_to_stderr_with_location);
27✔
155

156
        int r = get_opts(argc, argv);
27✔
157
        if (r < 0) {
27✔
158
                return EXIT_FAILURE;
27✔
159
        } else if (r > 0) {
25✔
160
                return EXIT_SUCCESS;
161
        }
162

163
        _cleanup_free_ char *node_name = NULL;
27✔
164
        _cleanup_free_ char *unit_name = NULL;
21✔
165
        parse_node_unit_opt(opt_node_unit, &node_name, &unit_name);
21✔
166

167
        _cleanup_sd_event_ sd_event *event = NULL;
21✔
168
        r = sd_event_default(&event);
21✔
169
        if (r < 0) {
21✔
170
                fprintf(stderr, "Failed to create event loop: %s", strerror(-r));
×
171
                return EXIT_FAILURE;
172
        }
173

174
        _cleanup_sd_bus_ sd_bus *api_bus = NULL;
21✔
175
        if (opt_user || ALWAYS_USER_API_BUS) {
21✔
176
                api_bus = user_bus_open(event);
×
177
        } else {
178
                api_bus = system_bus_open(event);
21✔
179
        }
180
        if (api_bus == NULL) {
21✔
181
                bc_log_error("Failed to create api bus");
×
182
                return EXIT_FAILURE;
183
        }
184

185
        /* Don't time out in the proxy calls, we want to wait until the target service is running */
186
        sd_bus_set_method_call_timeout(api_bus, UINT64_MAX);
21✔
187

188
        /* lint complains due to passing NULL. check for NULL done in other func. Disabling it. */
189
        // NOLINTNEXTLINE
190
        if (streqi(opt_operation, OPT_OPERATION_CREATE)) {
21✔
191
                r = call_proxy_method(api_bus, "CreateProxy", opt_node_unit, node_name, unit_name);
13✔
192
        } else if (streqi(opt_operation, OPT_OPERATION_REMOVE)) {
8✔
193
                r = call_proxy_method(api_bus, "RemoveProxy", opt_node_unit, node_name, unit_name);
8✔
194
        }
195

196
        if (r < 0) {
21✔
197
                return EXIT_FAILURE;
3✔
198
        }
199
        return EXIT_SUCCESS;
200
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc