Skip to content

Commit 716f5fc

Browse files
jeanseb6windrjarry
authored andcommitted
connection: add install, update and remove in batch
Sysrepo implemented nex function allowing to install, update and remove modules in batch. It allows to spend less time installinf lot of modules. This patch allows to call theses function with the Python wrapper.
1 parent 4d6f033 commit 716f5fc

File tree

6 files changed

+126
-13
lines changed

6 files changed

+126
-13
lines changed

README.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ On a Debian/Ubuntu system:
4949
Compatibility
5050
-------------
5151

52-
The current version requires at least C `sysrepo 2.1.66`__.
52+
The current version requires at least C `sysrepo 2.2.0`__.
5353

5454
The last version of the bindings that works with C `sysrepo 1.x`__ is v0.7.0__.
5555

56-
__ https://github.com/sysrepo/sysrepo/commit/a2a45fb32542
56+
__ https://github.com/sysrepo/sysrepo/commit/8c48a7a50eb2
5757
__ https://github.com/sysrepo/sysrepo/tree/libyang1
5858
__ https://pypi.org/project/sysrepo/0.7.0/
5959

cffi/cdefs.h

+3
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,11 @@ int sr_disconnect(sr_conn_ctx_t *);
8181
const struct ly_ctx *sr_acquire_context(sr_conn_ctx_t *);
8282
void sr_release_context(sr_conn_ctx_t *);
8383
int sr_install_module(sr_conn_ctx_t *, const char *, const char *, const char **);
84+
int sr_install_modules(sr_conn_ctx_t *conn, const char **, const char *, const char ***);
8485
int sr_remove_module(sr_conn_ctx_t *, const char *, int);
86+
int sr_remove_modules(sr_conn_ctx_t *conn, const char **, int);
8587
int sr_update_module(sr_conn_ctx_t *, const char *, const char *);
88+
int sr_update_modules(sr_conn_ctx_t *, const char **, const char *);
8689
int sr_enable_module_feature(sr_conn_ctx_t *, const char *, const char *);
8790
int sr_disable_module_feature(sr_conn_ctx_t *, const char *, const char *);
8891

cffi/source.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
#if (SR_VERSION_MAJOR != 7)
1010
#error "This version of sysrepo bindings only works with libsysrepo.so.7"
1111
#endif
12-
#if (SR_VERSION_MINOR < 7)
13-
#error "Need at least libsysrepo.so.7.7"
12+
#if (SR_VERSION_MINOR < 10)
13+
#error "Need at least libsysrepo.so.7.10"
1414
#endif

examples/sysrepo-example2.yang

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module sysrepo-example2 {
2+
yang-version 1.1;
3+
namespace a;
4+
prefix aug;
5+
6+
feature turbo2;
7+
}

sysrepo/connection.py

+92-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from contextlib import contextmanager
55
import logging
66
import signal
7-
from typing import Optional, Sequence
7+
from typing import Dict, Optional, Sequence
88

99
import libyang
1010

@@ -166,6 +166,87 @@ def install_module(
166166
valid_codes=valid_codes,
167167
)
168168

169+
def install_modules(
170+
self,
171+
filepaths: Dict[str, Sequence[str]],
172+
searchdirs: Optional[Sequence[str]] = None,
173+
ignore_already_exists=False,
174+
) -> None:
175+
"""
176+
Install new schemas (modules) into sysrepo in a batch.
177+
178+
:arg filepaths:
179+
Dict of paths to the new schemas associated with a list of features to enable.
180+
Can have either YANG or YIN extension/format.
181+
:arg searchdirs:
182+
Optional list of search directories for import schemas.
183+
:arg ignore_already_exists:
184+
Ignore error if module already exists in sysrepo.
185+
"""
186+
schema_paths = tuple([str2c(k) for k in filepaths] + [ffi.NULL])
187+
188+
# We need to maintain a pointer to extension names in C
189+
_ref = []
190+
all_features = []
191+
has_feature = False
192+
for features in filepaths.values():
193+
features_cname = []
194+
for f in features:
195+
cname = str2c(f)
196+
_ref.append(cname)
197+
features_cname.append(cname)
198+
has_feature = True
199+
200+
all_features.append(ffi.new("char *[]", tuple(features_cname + [ffi.NULL])))
201+
202+
if has_feature:
203+
all_features = tuple(all_features)
204+
else:
205+
all_features = ffi.NULL
206+
207+
if ignore_already_exists:
208+
valid_codes = (lib.SR_ERR_OK, lib.SR_ERR_EXISTS)
209+
else:
210+
valid_codes = (lib.SR_ERR_OK,)
211+
212+
if not searchdirs:
213+
searchdirs = []
214+
215+
check_call(
216+
lib.sr_install_modules,
217+
self.cdata,
218+
schema_paths,
219+
str2c(":".join(searchdirs)),
220+
all_features,
221+
valid_codes=valid_codes,
222+
)
223+
224+
def update_modules(
225+
self,
226+
filepaths: Sequence[str],
227+
searchdirs: Optional[Sequence[str]] = None,
228+
) -> None:
229+
"""
230+
Update schemas (modules) into sysrepo in a batch.
231+
232+
:arg filepaths:
233+
Array of paths to the new schemas.
234+
Can have either YANG or YIN extension/format.
235+
:arg searchdirs:
236+
Optional list of search directories for import schemas.
237+
"""
238+
schema_paths = tuple([str2c(path) for path in filepaths] + [ffi.NULL])
239+
if not searchdirs:
240+
searchdirs = []
241+
242+
check_call(
243+
lib.sr_update_modules,
244+
self.cdata,
245+
schema_paths,
246+
str2c(":".join(searchdirs)),
247+
valid_codes=(lib.SR_ERR_OK,),
248+
)
249+
169250
def remove_module(self, name: str, force: bool = False) -> None:
170251
"""
171252
Remove an installed module from sysrepo. Deferred until there are no
@@ -176,6 +257,16 @@ def remove_module(self, name: str, force: bool = False) -> None:
176257
"""
177258
check_call(lib.sr_remove_module, self.cdata, str2c(name), force)
178259

260+
def remove_modules(self, names: Sequence[str], force: bool = False) -> None:
261+
"""
262+
Remove installed modules from sysrepo.
263+
264+
:arg str names:
265+
Array of names of the modules to remove.
266+
"""
267+
names = tuple([str2c(n) for n in names] + [ffi.NULL])
268+
check_call(lib.sr_remove_modules, self.cdata, names, force)
269+
179270
def enable_module_feature(self, name: str, feature_name: str) -> None:
180271
"""
181272
Enable a module feature.

tests/test_connection.py

+20-8
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,28 @@ def test_conn_start_session_operational(self):
4242
with conn.start_session("operational") as sess:
4343
self.assertEqual(sess.get_datastore(), "operational")
4444

45-
def test_conn_install_module(self):
45+
def test_conn_install_remove_modules(self):
46+
YANG_FILE2 = os.path.join(
47+
os.path.dirname(os.path.dirname(__file__)), "examples/sysrepo-example2.yang"
48+
)
49+
with sysrepo.SysrepoConnection() as conn:
50+
filepaths = {YANG_FILE: ["turbo"], YANG_FILE2: ["turbo2"]}
51+
# filepaths = {YANG_FILE2: ["turbo2"]}
52+
conn.install_modules(filepaths)
53+
54+
with sysrepo.SysrepoConnection() as conn:
55+
modules = ["sysrepo-example", "sysrepo-example2"]
56+
conn.remove_modules(modules)
57+
58+
def test_conn_install_remove_module(self):
4659
with sysrepo.SysrepoConnection() as conn:
4760
conn.install_module(YANG_FILE, enabled_features=["turbo"])
61+
with sysrepo.SysrepoConnection() as conn:
62+
conn.remove_module("sysrepo-example")
63+
with sysrepo.SysrepoConnection() as conn:
64+
with conn.get_ly_ctx() as ctx:
65+
with self.assertRaises(libyang.LibyangError):
66+
ctx.get_module("sysrepo-example")
4867

4968
def test_conn_enable_module_feature(self):
5069
with sysrepo.SysrepoConnection() as conn:
@@ -57,11 +76,4 @@ def test_conn_enable_module_feature(self):
5776
data = data["module"]
5877
data = [x for x in data if x["name"] == "sysrepo-example"][0]
5978
self.assertIn("feature", data)
60-
61-
def test_conn_remove_module(self):
62-
with sysrepo.SysrepoConnection() as conn:
6379
conn.remove_module("sysrepo-example")
64-
with sysrepo.SysrepoConnection() as conn:
65-
with conn.get_ly_ctx() as ctx:
66-
with self.assertRaises(libyang.LibyangError):
67-
ctx.get_module("sysrepo-example")

0 commit comments

Comments
 (0)