Skip to content

Commit 2cf7984

Browse files
jeanseb6windrjarry
authored andcommitted
Port to libyang2/sysrepo2
Add support for the new major versions of libyang.so and libsysrepo.so. Various parts of the API have been changed. Mainly around get_ly_ctx() which now returns a context manager which releases the acquired libyang context pointer when closed. Signed-off-by: Jean-Sébastien Bevilacqua <[email protected]> Signed-off-by: Robin Jarry <[email protected]>
1 parent 27b5d41 commit 2cf7984

20 files changed

+472
-335
lines changed

MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
include README.rst
22
include cffi/build.py
33
include cffi/cdefs.h
4+
include cffi/source.c
45
include pyproject.toml
56
include setup.cfg
67
include setup.py

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ lint:
77
tox -e lint
88

99
tests:
10-
tox -e py3-libyang1
10+
tox -e py3
1111

1212
format:
1313
tox -e format

cffi/build.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@ def search_paths(env_var: str) -> List[str]:
3030
EXTRA_CFLAGS += shlex.split(os.environ.get("SYSREPO_EXTRA_CFLAGS", ""))
3131
EXTRA_LDFLAGS = shlex.split(os.environ.get("SYSREPO_EXTRA_LDFLAGS", ""))
3232

33-
BUILDER.set_source(
34-
"_sysrepo",
35-
"#include <sysrepo.h>",
36-
libraries=["sysrepo", "yang"],
37-
extra_compile_args=EXTRA_CFLAGS,
38-
extra_link_args=EXTRA_LDFLAGS,
39-
include_dirs=HEADERS,
40-
library_dirs=LIBRARIES,
41-
py_limited_api=False,
42-
)
33+
with open(os.path.join(HERE, "source.c"), encoding="utf-8") as f:
34+
BUILDER.set_source(
35+
"_sysrepo",
36+
f.read(),
37+
libraries=["sysrepo", "yang"],
38+
extra_compile_args=EXTRA_CFLAGS,
39+
extra_link_args=EXTRA_LDFLAGS,
40+
include_dirs=HEADERS,
41+
library_dirs=LIBRARIES,
42+
py_limited_api=False,
43+
)
4344

4445
if __name__ == "__main__":
4546
BUILDER.compile()

cffi/cdefs.h

+58-46
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ typedef enum sr_error_e {
88
SR_ERR_INVAL_ARG,
99
SR_ERR_LY,
1010
SR_ERR_SYS,
11-
SR_ERR_NOMEM,
11+
SR_ERR_NO_MEMORY,
1212
SR_ERR_NOT_FOUND,
1313
SR_ERR_EXISTS,
1414
SR_ERR_INTERNAL,
@@ -45,8 +45,7 @@ typedef struct sr_conn_ctx_s sr_conn_ctx_t;
4545
typedef struct sr_session_ctx_s sr_session_ctx_t;
4646
typedef enum sr_conn_flag_e {
4747
SR_CONN_CACHE_RUNNING,
48-
SR_CONN_NO_SCHED_CHANGES,
49-
SR_CONN_ERR_ON_SCHED_FAIL,
48+
SR_CONN_CTX_SET_PRIV_PARSED,
5049
...
5150
} sr_conn_flag_t;
5251
typedef uint32_t sr_conn_options_t;
@@ -57,25 +56,32 @@ typedef enum sr_datastore_e {
5756
SR_DS_OPERATIONAL,
5857
...
5958
} sr_datastore_t;
60-
typedef struct sr_error_info_msg_s {
59+
typedef struct sr_error_info_err_s {
60+
sr_error_t err_code;
6161
char *message;
62-
char *xpath;
63-
} sr_error_info_msg_t;
62+
char *error_format;
63+
void *error_data;
64+
} sr_error_info_err_t;
6465
typedef struct sr_error_info_s {
65-
sr_error_t err_code;
66-
sr_error_info_msg_t *err;
67-
size_t err_count;
66+
sr_error_info_err_t *err;
67+
uint32_t err_count;
6868
} sr_error_info_t;
6969

7070
/* forward declarations from libyang */
7171
struct ly_ctx;
7272
struct lyd_node;
73+
typedef int... time_t;
74+
struct timespec {
75+
time_t tv_sec;
76+
long tv_nsec;
77+
};
7378

7479
int sr_connect(const sr_conn_options_t, sr_conn_ctx_t **);
7580
int sr_disconnect(sr_conn_ctx_t *);
76-
const struct ly_ctx *sr_get_context(sr_conn_ctx_t *);
77-
int sr_install_module(sr_conn_ctx_t *, const char *, const char *, const char **, int);
78-
int sr_remove_module(sr_conn_ctx_t *, const char *);
81+
const struct ly_ctx *sr_acquire_context(sr_conn_ctx_t *);
82+
void sr_release_context(sr_conn_ctx_t *);
83+
int sr_install_module(sr_conn_ctx_t *, const char *, const char *, const char **);
84+
int sr_remove_module(sr_conn_ctx_t *, const char *, int);
7985
int sr_update_module(sr_conn_ctx_t *, const char *, const char *);
8086
int sr_enable_module_feature(sr_conn_ctx_t *, const char *, const char *);
8187
int sr_disable_module_feature(sr_conn_ctx_t *, const char *, const char *);
@@ -85,12 +91,14 @@ int sr_session_stop(sr_session_ctx_t *);
8591
int sr_session_switch_ds(sr_session_ctx_t *, sr_datastore_t);
8692
sr_datastore_t sr_session_get_ds(sr_session_ctx_t *);
8793
sr_conn_ctx_t *sr_session_get_connection(sr_session_ctx_t *);
88-
uint32_t sr_session_get_event_nc_id(sr_session_ctx_t *);
89-
const char *sr_session_get_event_user(sr_session_ctx_t *);
90-
int sr_get_error(sr_session_ctx_t *, const sr_error_info_t **);
91-
int sr_set_error(sr_session_ctx_t *, const char *, const char *, ...);
94+
int sr_session_get_error(sr_session_ctx_t *, const sr_error_info_t **);
95+
int sr_session_set_error_message(sr_session_ctx_t *, const char *, ...);
96+
const char *sr_session_get_orig_name(sr_session_ctx_t *session);
97+
int sr_session_set_orig_name(sr_session_ctx_t *session, const char *);
98+
int sr_session_get_orig_data(sr_session_ctx_t *session, uint32_t idx, uint32_t *size, const void **data);
99+
int sr_session_push_orig_data(sr_session_ctx_t * session, uint32_t size, const void *data);
92100

93-
typedef enum sr_type_e {
101+
typedef enum sr_val_type_e {
94102
SR_UNKNOWN_T,
95103
SR_LIST_T,
96104
SR_CONTAINER_T,
@@ -115,11 +123,11 @@ typedef enum sr_type_e {
115123
SR_ANYXML_T,
116124
SR_ANYDATA_T,
117125
...
118-
} sr_type_t;
119-
typedef union sr_data_u {
126+
} sr_val_type_t;
127+
typedef union sr_val_data_u {
120128
char *binary_val;
121129
char *bits_val;
122-
bool bool_val;
130+
int bool_val;
123131
double decimal64_val;
124132
char *enum_val;
125133
char *identityref_val;
@@ -136,11 +144,11 @@ typedef union sr_data_u {
136144
char *anyxml_val;
137145
char *anydata_val;
138146
...;
139-
} sr_data_t;
147+
} sr_val_data_t;
140148
typedef struct sr_val_s {
141149
char *xpath;
142-
sr_type_t type;
143-
sr_data_t data;
150+
sr_val_type_t type;
151+
sr_val_data_t data;
144152
...;
145153
} sr_val_t;
146154
typedef enum sr_edit_flag_e {
@@ -159,42 +167,46 @@ typedef enum sr_get_oper_flag_e {
159167
} sr_get_oper_flag_t;
160168
typedef uint32_t sr_get_oper_options_t;
161169

170+
struct sr_data_s {
171+
const sr_conn_ctx_t *conn;
172+
struct lyd_node *tree;
173+
};
174+
typedef struct sr_data_s sr_data_t;
175+
162176
void sr_free_val(sr_val_t *);
163177
void sr_free_values(sr_val_t *, size_t);
164178

165179
int sr_get_item(sr_session_ctx_t *, const char *, uint32_t, sr_val_t **);
166180
int sr_get_items(sr_session_ctx_t *, const char *, uint32_t,
167181
const sr_get_oper_options_t, sr_val_t **, size_t *);
168182
int sr_get_data(sr_session_ctx_t *, const char *, uint32_t, uint32_t,
169-
const sr_get_oper_options_t, struct lyd_node **);
170-
int sr_rpc_send_tree(
171-
sr_session_ctx_t *, struct lyd_node *, uint32_t, struct lyd_node **);
183+
const sr_get_oper_options_t, sr_data_t **);
184+
void sr_release_data(sr_data_t *);
185+
int sr_rpc_send_tree(sr_session_ctx_t *, struct lyd_node *, uint32_t, sr_data_t **);
172186

173187
int sr_set_item_str(sr_session_ctx_t *, const char *, const char *, const char *, const sr_edit_options_t);
174188
int sr_delete_item(sr_session_ctx_t *, const char *, const sr_edit_options_t);
175189
int sr_edit_batch(sr_session_ctx_t *, const struct lyd_node *, const char *);
176-
int sr_replace_config(sr_session_ctx_t *, const char *, struct lyd_node *, uint32_t, int);
190+
int sr_replace_config(sr_session_ctx_t *, const char *, struct lyd_node *, uint32_t);
177191
int sr_validate(sr_session_ctx_t *, const char *, uint32_t);
178-
int sr_apply_changes(sr_session_ctx_t *, uint32_t, int);
192+
int sr_apply_changes(sr_session_ctx_t *, uint32_t);
179193
int sr_discard_changes(sr_session_ctx_t *);
180194

181195
typedef enum sr_subscr_flag_e {
182-
SR_SUBSCR_CTX_REUSE,
183196
SR_SUBSCR_NO_THREAD,
184197
SR_SUBSCR_PASSIVE,
185198
SR_SUBSCR_DONE_ONLY,
186199
SR_SUBSCR_ENABLED,
187200
SR_SUBSCR_UPDATE,
188-
SR_SUBSCR_UNLOCKED,
201+
SR_SUBSCR_OPER_MERGE,
189202
...
190203
} sr_subscr_flag_t;
191204

192205
typedef struct sr_subscription_ctx_s sr_subscription_ctx_t;
193206
typedef uint32_t sr_subscr_options_t;
194207

195208
int sr_get_event_pipe(sr_subscription_ctx_t *, int *);
196-
typedef int... time_t;
197-
int sr_process_events(sr_subscription_ctx_t *, sr_session_ctx_t *, time_t *);
209+
int sr_subscription_process_events(sr_subscription_ctx_t *, sr_session_ctx_t *, struct timespec *);
198210
int sr_unsubscribe(sr_subscription_ctx_t *);
199211

200212
typedef enum sr_event_e {
@@ -221,50 +233,50 @@ int sr_get_change_next(
221233
int sr_get_change_tree_next(
222234
sr_session_ctx_t *, sr_change_iter_t *, sr_change_oper_t *,
223235
const struct lyd_node **, const char **prev_val,
224-
const char **prev_list, bool *prev_dflt);
236+
const char **prev_list, int *prev_dflt);
225237
void sr_free_change_iter(sr_change_iter_t *);
226238

227239

228240
extern "Python" int srpy_module_change_cb(
229-
sr_session_ctx_t *, const char *module, const char *xpath,
241+
sr_session_ctx_t *, uint32_t sub_id, const char *module, const char *xpath,
230242
sr_event_t, uint32_t req_id, void *priv);
231243
int sr_module_change_subscribe(
232244
sr_session_ctx_t *, const char *module, const char *xpath,
233-
int (*)(sr_session_ctx_t *, const char *, const char *, sr_event_t, uint32_t, void *),
245+
int (*)(sr_session_ctx_t *, uint32_t, const char *, const char *, sr_event_t, uint32_t, void *),
234246
void *priv, uint32_t priority, sr_subscr_options_t, sr_subscription_ctx_t **);
235247

236248
extern "Python" int srpy_rpc_tree_cb(
237-
sr_session_ctx_t *, const char *, const struct lyd_node *input,
249+
sr_session_ctx_t *, uint32_t sub_id, const char *, const struct lyd_node *input,
238250
sr_event_t, uint32_t req_id, struct lyd_node *output, void *priv);
239251
int sr_rpc_subscribe_tree(
240252
sr_session_ctx_t *, const char *xpath,
241-
int (*)(sr_session_ctx_t *, const char *, const struct lyd_node *, sr_event_t, uint32_t, struct lyd_node *, void *),
253+
int (*)(sr_session_ctx_t *, uint32_t, const char *, const struct lyd_node *, sr_event_t, uint32_t, struct lyd_node *, void *),
242254
void *priv, uint32_t priority, sr_subscr_options_t, sr_subscription_ctx_t **);
243255

244256
extern "Python" int srpy_oper_data_cb(
245-
sr_session_ctx_t *, const char *module, const char *xpath,
257+
sr_session_ctx_t *, uint32_t sub_id, const char *module, const char *xpath,
246258
const char *req_xpath, uint32_t req_id, struct lyd_node **, void *priv);
247-
int sr_oper_get_items_subscribe(
259+
int sr_oper_get_subscribe(
248260
sr_session_ctx_t *, const char *module, const char *xpath,
249-
int (*)(sr_session_ctx_t *, const char *, const char *, const char *, uint32_t, struct lyd_node **, void *),
261+
int (*)(sr_session_ctx_t *, uint32_t, const char *, const char *, const char *, uint32_t, struct lyd_node **, void *),
250262
void *priv, sr_subscr_options_t, sr_subscription_ctx_t **);
251263

252264
typedef enum sr_ev_notif_type_e {
253265
SR_EV_NOTIF_REALTIME,
254266
SR_EV_NOTIF_REPLAY,
255267
SR_EV_NOTIF_REPLAY_COMPLETE,
256-
SR_EV_NOTIF_STOP,
268+
SR_EV_NOTIF_TERMINATED,
257269
SR_EV_NOTIF_SUSPENDED,
258270
SR_EV_NOTIF_RESUMED,
259271
...
260272
} sr_ev_notif_type_t;
261273

262274
extern "Python" void srpy_event_notif_tree_cb(
263-
sr_session_ctx_t *, const sr_ev_notif_type_t notif_type, const struct lyd_node *notif,
264-
time_t timestamp, void *priv);
275+
sr_session_ctx_t *, uint32_t sub_id, const sr_ev_notif_type_t notif_type, const struct lyd_node *notif,
276+
struct timespec* timestamp, void *priv);
265277

266-
int sr_event_notif_subscribe_tree(sr_session_ctx_t *, const char *module_name, const char *xpath, time_t start_time, time_t stop_time,
267-
void (*)(sr_session_ctx_t *, const sr_ev_notif_type_t, const struct lyd_node*, time_t, void*),
278+
int sr_notif_subscribe_tree(sr_session_ctx_t *, const char *module_name, const char *xpath, struct timespec *start_time, struct timespec *stop_time,
279+
void (*)(sr_session_ctx_t *, uint32_t, const sr_ev_notif_type_t, const struct lyd_node*, struct timespec*, void*),
268280
void *priv, sr_subscr_options_t, sr_subscription_ctx_t **);
269281

270-
int sr_event_notif_send_tree(sr_session_ctx_t *, struct lyd_node *notif);
282+
int sr_notif_send_tree(sr_session_ctx_t *, struct lyd_node *notif, uint32_t timeout_ms, int wait);

cffi/source.c

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Copyright (c) 2022 Robin Jarry
3+
* SPDX-License-Identifier: BSD-3-Clause
4+
*/
5+
6+
#include <sysrepo.h>
7+
#include <sysrepo/version.h>
8+
9+
#if (SR_VERSION_MAJOR != 7)
10+
#error "This version of sysrepo bindings only works with sysrepo 7.x"
11+
#endif
12+
#if (SR_VERSION_MINOR < 6)
13+
#error "Need at least sysrepo 7.6"
14+
#endif

examples/sysrepocfg.py

+22-26
Original file line numberDiff line numberDiff line change
@@ -90,41 +90,37 @@ def main():
9090

9191
try:
9292
with sysrepo.SysrepoConnection() as conn:
93-
ctx = conn.get_ly_ctx()
9493
with conn.start_session(args.datastore) as sess:
9594
if args.import_:
96-
data = ctx.parse_data_mem(
97-
sys.stdin.read(),
98-
args.format,
99-
config=True,
100-
strict=not args.not_strict,
101-
)
102-
sess.replace_config_ly(data, args.import_)
95+
with conn.get_ly_ctx() as ctx:
96+
data = ctx.parse_data_mem(
97+
sys.stdin.read(),
98+
args.format,
99+
no_state=True,
100+
strict=not args.not_strict,
101+
)
102+
sess.replace_config_ly(data, args.import_)
103103

104104
elif args.export:
105-
data = sess.get_data_ly(args.export)
106-
try:
105+
with sess.get_data_ly(args.export) as data:
107106
data.print_file(
108107
sys.stdout, args.format, pretty=True, with_siblings=True
109108
)
110-
finally:
111-
data.free()
112109

113110
elif args.rpc:
114-
rpc_input = ctx.parse_data_mem(
115-
sys.stdin.read(),
116-
args.format,
117-
rpc=True,
118-
strict=not args.not_strict,
119-
)
120-
try:
121-
rpc_output = sess.rpc_send_ly(rpc_input)
122-
finally:
123-
rpc_input.free()
124-
try:
125-
rpc_output.print_file(sys.stdout, args.format, pretty=True)
126-
finally:
127-
rpc_output.free()
111+
with conn.get_ly_ctx() as ctx:
112+
rpc_input = ctx.parse_data_mem(
113+
sys.stdin.read(),
114+
args.format,
115+
strict=not args.not_strict,
116+
)
117+
with sess.rpc_send_ly(rpc_input) as rpc_output:
118+
try:
119+
rpc_output.print_file(
120+
sys.stdout, args.format, pretty=True
121+
)
122+
finally:
123+
rpc_input.free()
128124

129125
return 0
130126
except sysrepo.SysrepoError as e:

0 commit comments

Comments
 (0)