mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
Bump sysrepo, netopeer,libyang and libnetconf2
A lot of changes in sysrepo, required to add extra patches (bugfixes) to sysrepo, sysrepo-cpp and rousette.
This commit is contained in:
+1
-1
Submodule buildroot updated: 8cf431f9fb...e5315dbce8
@@ -0,0 +1,82 @@
|
||||
From d0f6422fee7a46fcb7445c88f499f61b3eb0ead0 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Piecek <Adam.Piecek@cesnet.cz>
|
||||
Date: Wed, 23 Oct 2024 14:37:09 +0200
|
||||
Subject: [PATCH 1/8] added support for RpcYang in Context::parseOp
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Change-Id: I25182ea2d042be1e6e4246e18aee260cc032e547
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/Context.cpp | 6 ++++--
|
||||
tests/context.cpp | 21 +++++++++++++++++++++
|
||||
2 files changed, 25 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/Context.cpp b/src/Context.cpp
|
||||
index b844bd9..287f8c8 100644
|
||||
--- a/src/Context.cpp
|
||||
+++ b/src/Context.cpp
|
||||
@@ -221,7 +221,8 @@ std::optional<DataNode> Context::parseExtData(
|
||||
* - a NETCONF RPC,
|
||||
* - a NETCONF notification,
|
||||
* - a RESTCONF notification,
|
||||
- * - a YANG notification.
|
||||
+ * - a YANG notification,
|
||||
+ * - a YANG RPC.
|
||||
*
|
||||
* Parsing any of these requires just the schema (which is available through the Context), and the textual payload.
|
||||
* All the other information are encoded in the textual payload as per the standard.
|
||||
@@ -243,6 +244,7 @@ ParsedOp Context::parseOp(const std::string& input, const DataFormat format, con
|
||||
auto in = wrap_ly_in_new_memory(input);
|
||||
|
||||
switch (opType) {
|
||||
+ case OperationType::RpcYang:
|
||||
case OperationType::RpcNetconf:
|
||||
case OperationType::NotificationNetconf:
|
||||
case OperationType::NotificationRestconf:
|
||||
@@ -254,7 +256,7 @@ ParsedOp Context::parseOp(const std::string& input, const DataFormat format, con
|
||||
ParsedOp res;
|
||||
res.tree = tree ? std::optional{libyang::wrapRawNode(tree)} : std::nullopt;
|
||||
|
||||
- if (opType == OperationType::NotificationYang) {
|
||||
+ if ((opType == OperationType::NotificationYang) || (opType == OperationType::RpcYang)) {
|
||||
res.op = op && tree ? std::optional{DataNode(op, res.tree->m_refs)} : std::nullopt;
|
||||
} else {
|
||||
res.op = op ? std::optional{libyang::wrapRawNode(op)} : std::nullopt;
|
||||
diff --git a/tests/context.cpp b/tests/context.cpp
|
||||
index 71ae873..11019eb 100644
|
||||
--- a/tests/context.cpp
|
||||
+++ b/tests/context.cpp
|
||||
@@ -464,6 +464,27 @@ TEST_CASE("context")
|
||||
REQUIRE(data->findPath("/example-schema:leafInt8")->asTerm().valueStr() == "-43");
|
||||
}
|
||||
|
||||
+ DOCTEST_SUBCASE("Context::parseOp")
|
||||
+ {
|
||||
+ DOCTEST_SUBCASE("RPC")
|
||||
+ {
|
||||
+ ctx->parseModule(example_schema, libyang::SchemaFormat::YANG);
|
||||
+ std::string dataJson = R"({"example-schema:myRpc":{"inputLeaf":"str"}})";
|
||||
+ auto pop = ctx->parseOp(dataJson, libyang::DataFormat::JSON, libyang::OperationType::RpcYang);
|
||||
+ REQUIRE(pop.op->schema().name() == "myRpc");
|
||||
+ REQUIRE(pop.tree->findPath("/example-schema:myRpc/inputLeaf")->asTerm().valueStr() == "str");
|
||||
+ }
|
||||
+ DOCTEST_SUBCASE("action")
|
||||
+ {
|
||||
+ ctx->parseModule(example_schema, libyang::SchemaFormat::YANG);
|
||||
+ std::string datajson = R"({"example-schema:person":[{"name":"john", "poke":{}}]})";
|
||||
+ auto pop = ctx->parseOp(datajson, libyang::DataFormat::JSON, libyang::OperationType::RpcYang);
|
||||
+ REQUIRE(pop.op->schema().name() == "poke");
|
||||
+ REQUIRE(pop.tree->findPath("/example-schema:person[name='john']/poke")->schema().nodeType() == libyang::NodeType::Action);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
DOCTEST_SUBCASE("Context::parseExt")
|
||||
{
|
||||
ctx->setSearchDir(TESTS_DIR / "yang");
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
From 7e015f3486bdbb54f1dcc2e2ce51102b1d623081 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
|
||||
Date: Wed, 23 Oct 2024 12:52:24 +0200
|
||||
Subject: [PATCH 2/8] throw when lyd_validate_all returns error
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Bug: https://github.com/CESNET/libyang-cpp/issues/20
|
||||
Change-Id: I005a2f1b057978573a4046e7b4cc31d77e36fde3
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/DataNode.cpp | 4 +++-
|
||||
tests/data_node.cpp | 7 +++++++
|
||||
2 files changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/DataNode.cpp b/src/DataNode.cpp
|
||||
index 51c86c8..2ef17f2 100644
|
||||
--- a/src/DataNode.cpp
|
||||
+++ b/src/DataNode.cpp
|
||||
@@ -1170,7 +1170,9 @@ void validateAll(std::optional<libyang::DataNode>& node, const std::optional<Val
|
||||
}
|
||||
|
||||
// TODO: support the `diff` argument
|
||||
- lyd_validate_all(node ? &node->m_node : nullptr, nullptr, opts ? utils::toValidationOptions(*opts) : 0, nullptr);
|
||||
+ auto ret = lyd_validate_all(node ? &node->m_node : nullptr, nullptr, opts ? utils::toValidationOptions(*opts) : 0, nullptr);
|
||||
+ throwIfError(ret, "libyang:validateAll: lyd_validate_all failed");
|
||||
+
|
||||
if (!node->m_node) {
|
||||
node = std::nullopt;
|
||||
}
|
||||
diff --git a/tests/data_node.cpp b/tests/data_node.cpp
|
||||
index a23e4c2..8a2610e 100644
|
||||
--- a/tests/data_node.cpp
|
||||
+++ b/tests/data_node.cpp
|
||||
@@ -489,6 +489,13 @@ TEST_CASE("Data Node manipulation")
|
||||
REQUIRE_THROWS_WITH_AS(libyang::validateAll(node, libyang::ValidationOptions::NoState), "validateAll: Node is not a unique reference", libyang::Error);
|
||||
}
|
||||
|
||||
+ DOCTEST_SUBCASE("validateAll throws on validation failure")
|
||||
+ {
|
||||
+ ctx.parseModule(type_module, libyang::SchemaFormat::YANG);
|
||||
+ auto node = std::optional{ctx.newPath("/type_module:leafWithConfigFalse", "hi")};
|
||||
+ REQUIRE_THROWS_WITH_AS(libyang::validateAll(node, libyang::ValidationOptions::NoState), "libyang:validateAll: lyd_validate_all failed: LY_EVALID", libyang::ErrorWithCode);
|
||||
+ }
|
||||
+
|
||||
DOCTEST_SUBCASE("unlink")
|
||||
{
|
||||
auto root = ctx.parseData(data2, libyang::DataFormat::JSON);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 490d8bb242d33213b948485f5b94c55e22cf86a6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Thu, 21 Nov 2024 11:32:44 +0100
|
||||
Subject: [PATCH 3/8] remove a misleading comment
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
The whole intention within action's input/output handling here was to
|
||||
put some emphasis on the fact that we aren't tracking the input/output
|
||||
nodes directly. However, looking at all the other classes this is a bit
|
||||
redundant, we're using a pattern like this all the time. Just drop the
|
||||
comment.
|
||||
|
||||
Change-Id: Ibd9bf9f1e83c650dda3bc43ef48e61dd6d95da5a
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/SchemaNode.cpp | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/src/SchemaNode.cpp b/src/SchemaNode.cpp
|
||||
index 81e938f..9934cea 100644
|
||||
--- a/src/SchemaNode.cpp
|
||||
+++ b/src/SchemaNode.cpp
|
||||
@@ -640,9 +640,6 @@ bool List::isUserOrdered() const
|
||||
*/
|
||||
ActionRpcInput ActionRpc::input() const
|
||||
{
|
||||
- // I need a lysc_node* for ActionRpcInput, but m_node->input is a lysp_node_action_inout. lysp_node_action_inout is
|
||||
- // still just a lysc_node, so I'll just convert to lysc_node.
|
||||
- // This is not very pretty, but I don't want to introduce another member for ActionRpcInput and ActionRpcOutput.
|
||||
return ActionRpcInput{reinterpret_cast<const lysc_node*>(&reinterpret_cast<const lysc_node_action*>(m_node)->input), m_ctx};
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From e1b17386cf61048d2fe27fffb3b763981a225f52 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bed=C5=99ich=20Schindler?= <bedrich.schindler@gmail.com>
|
||||
Date: Wed, 27 Nov 2024 09:47:47 +0100
|
||||
Subject: [PATCH 4/8] schema: improve `List::keys()` not to use `std::move`
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
`List::keys()` used `std::move` while iterating over array of leafs.
|
||||
This was solved without using `std::move`.
|
||||
|
||||
Change-Id: I8cbf8780ecd8848e46c1de5d4123a08624536bba
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/SchemaNode.cpp | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/SchemaNode.cpp b/src/SchemaNode.cpp
|
||||
index 9934cea..20e2aff 100644
|
||||
--- a/src/SchemaNode.cpp
|
||||
+++ b/src/SchemaNode.cpp
|
||||
@@ -593,8 +593,7 @@ std::vector<Leaf> List::keys() const
|
||||
LY_LIST_FOR(list->child, elem)
|
||||
{
|
||||
if (lysc_is_key(elem)) {
|
||||
- Leaf leaf(elem, m_ctx);
|
||||
- res.emplace_back(std::move(leaf));
|
||||
+ res.emplace_back(Leaf(elem, m_ctx));
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
From 1102ecdcafbc9206f59b383769687e418557838e Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bed=C5=99ich=20Schindler?= <bedrich.schindler@gmail.com>
|
||||
Date: Mon, 25 Nov 2024 15:54:02 +0100
|
||||
Subject: [PATCH 5/8] schema: make leaf-list's `default` statement available
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Make leaf-list's `default` statement available so that it can be
|
||||
accessed if end-user requires reading schema nodes.
|
||||
|
||||
`LeafList::defaultValuesStr()` returns array of canonized string default
|
||||
values.
|
||||
|
||||
Change-Id: Idc42cd877f1fd3d717d491d09c46b59492527bff
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
include/libyang-cpp/SchemaNode.hpp | 1 +
|
||||
src/SchemaNode.cpp | 17 +++++++++++++++++
|
||||
tests/context.cpp | 1 +
|
||||
tests/example_schema.hpp | 8 ++++++++
|
||||
tests/schema_node.cpp | 7 +++++++
|
||||
5 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/include/libyang-cpp/SchemaNode.hpp b/include/libyang-cpp/SchemaNode.hpp
|
||||
index 83afc06..8ddf9be 100644
|
||||
--- a/include/libyang-cpp/SchemaNode.hpp
|
||||
+++ b/include/libyang-cpp/SchemaNode.hpp
|
||||
@@ -169,6 +169,7 @@ class LIBYANG_CPP_EXPORT LeafList : public SchemaNode {
|
||||
public:
|
||||
bool isMandatory() const;
|
||||
types::Type valueType() const;
|
||||
+ std::vector<std::string> defaultValuesStr() const;
|
||||
libyang::types::constraints::ListSize maxElements() const;
|
||||
libyang::types::constraints::ListSize minElements() const;
|
||||
std::optional<std::string> units() const;
|
||||
diff --git a/src/SchemaNode.cpp b/src/SchemaNode.cpp
|
||||
index 9934cea..95bc09b 100644
|
||||
--- a/src/SchemaNode.cpp
|
||||
+++ b/src/SchemaNode.cpp
|
||||
@@ -472,6 +472,23 @@ types::Type LeafList::valueType() const
|
||||
return types::Type{reinterpret_cast<const lysc_node_leaflist*>(m_node)->type, typeParsed, m_ctx};
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * @brief Retrieves the default string values for this leaf-list.
|
||||
+ *
|
||||
+ * @return The default values, or an empty vector if the leaf-list does not have default values.
|
||||
+ *
|
||||
+ * Wraps `lysc_node_leaflist::dflts`.
|
||||
+ */
|
||||
+std::vector<std::string> LeafList::defaultValuesStr() const
|
||||
+{
|
||||
+ auto dflts = reinterpret_cast<const lysc_node_leaflist*>(m_node)->dflts;
|
||||
+ std::vector<std::string> res;
|
||||
+ for (const auto& it : std::span(dflts, LY_ARRAY_COUNT(dflts))) {
|
||||
+ res.emplace_back(lyd_value_get_canonical(m_ctx.get(), it));
|
||||
+ }
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* @brief Retrieves the units for this leaf.
|
||||
* @return The units, or std::nullopt if no units are available.
|
||||
diff --git a/tests/context.cpp b/tests/context.cpp
|
||||
index 11019eb..902faf6 100644
|
||||
--- a/tests/context.cpp
|
||||
+++ b/tests/context.cpp
|
||||
@@ -733,6 +733,7 @@ TEST_CASE("context")
|
||||
+--rw iid-valid? instance-identifier
|
||||
+--rw iid-relaxed? instance-identifier
|
||||
+--rw leafListBasic* string
|
||||
+ +--rw leafListWithDefault* int32
|
||||
+--rw leafListWithMinMaxElements* int32
|
||||
+--rw leafListWithUnits* int32
|
||||
+--rw listBasic* [primary-key]
|
||||
diff --git a/tests/example_schema.hpp b/tests/example_schema.hpp
|
||||
index c093f50..2861b1a 100644
|
||||
--- a/tests/example_schema.hpp
|
||||
+++ b/tests/example_schema.hpp
|
||||
@@ -525,6 +525,14 @@ module type_module {
|
||||
ordered-by user;
|
||||
}
|
||||
|
||||
+ leaf-list leafListWithDefault {
|
||||
+ type int32;
|
||||
+ default -1;
|
||||
+ default +512;
|
||||
+ default 0x400;
|
||||
+ default 04000;
|
||||
+ }
|
||||
+
|
||||
leaf-list leafListWithMinMaxElements {
|
||||
type int32;
|
||||
min-elements 1;
|
||||
diff --git a/tests/schema_node.cpp b/tests/schema_node.cpp
|
||||
index a86900d..80c7407 100644
|
||||
--- a/tests/schema_node.cpp
|
||||
+++ b/tests/schema_node.cpp
|
||||
@@ -200,6 +200,7 @@ TEST_CASE("SchemaNode")
|
||||
"/type_module:iid-valid",
|
||||
"/type_module:iid-relaxed",
|
||||
"/type_module:leafListBasic",
|
||||
+ "/type_module:leafListWithDefault",
|
||||
"/type_module:leafListWithMinMaxElements",
|
||||
"/type_module:leafListWithUnits",
|
||||
"/type_module:listBasic",
|
||||
@@ -606,6 +607,12 @@ TEST_CASE("SchemaNode")
|
||||
REQUIRE(!ctx->findPath("/type_module:leafListBasic").asLeafList().isMandatory());
|
||||
}
|
||||
|
||||
+ DOCTEST_SUBCASE("LeafList::defaultValuesStr")
|
||||
+ {
|
||||
+ REQUIRE(ctx->findPath("/type_module:leafListWithDefault").asLeafList().defaultValuesStr() == std::vector<std::string>{"-1", "512", "1024", "2048"});
|
||||
+ REQUIRE(ctx->findPath("/type_module:leafListBasic").asLeafList().defaultValuesStr().size() == 0);
|
||||
+ }
|
||||
+
|
||||
DOCTEST_SUBCASE("LeafList::maxElements")
|
||||
{
|
||||
REQUIRE(ctx->findPath("/type_module:leafListWithMinMaxElements").asLeafList().maxElements() == 5);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
From 01f2633cef60495d5cafc4b4b1f25273b03ab3cd Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Bed=C5=99ich=20Schindler?= <bedrich.schindler@gmail.com>
|
||||
Date: Tue, 22 Oct 2024 15:11:30 +0200
|
||||
Subject: [PATCH 6/8] schema: Make choice and case statements available
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Make choice and case statements available so that they can be accessed
|
||||
if end-user requires reading schema nodes.
|
||||
|
||||
By design, choice and case statements do not exist in data tree directly.
|
||||
Only children of one case can be present in the data tree at one time.
|
||||
That means that choice and case children are not instantiable, thus
|
||||
`SchemaNode::immediateChildren` must be used (instead of
|
||||
`SchemaNode::childInstantibles`) if end-user wants to access choice
|
||||
and case substatements.
|
||||
|
||||
Change-Id: Ib089672ad21dda8a0344895835d92d3432fcccb8
|
||||
Co-authored-by: Jan Kundrát <jan.kundrat@cesnet.cz>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
include/libyang-cpp/SchemaNode.hpp | 34 +++++++++++++
|
||||
src/SchemaNode.cpp | 68 ++++++++++++++++++++++++++
|
||||
tests/context.cpp | 77 +++++++++++++++++++-----------
|
||||
tests/example_schema.hpp | 60 +++++++++++++++++++++++
|
||||
tests/schema_node.cpp | 72 ++++++++++++++++++++++++++++
|
||||
5 files changed, 284 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/include/libyang-cpp/SchemaNode.hpp b/include/libyang-cpp/SchemaNode.hpp
|
||||
index 8ddf9be..0f1a4c4 100644
|
||||
--- a/include/libyang-cpp/SchemaNode.hpp
|
||||
+++ b/include/libyang-cpp/SchemaNode.hpp
|
||||
@@ -22,6 +22,8 @@ class AnyDataAnyXML;
|
||||
class ActionRpc;
|
||||
class ActionRpcInput;
|
||||
class ActionRpcOutput;
|
||||
+class Case;
|
||||
+class Choice;
|
||||
class Container;
|
||||
class Leaf;
|
||||
class LeafList;
|
||||
@@ -62,6 +64,8 @@ public:
|
||||
// drectly by the user.
|
||||
// TODO: turn these into a templated `as<>` method.
|
||||
AnyDataAnyXML asAnyDataAnyXML() const;
|
||||
+ Case asCase() const;
|
||||
+ Choice asChoice() const;
|
||||
Container asContainer() const;
|
||||
Leaf asLeaf() const;
|
||||
LeafList asLeafList() const;
|
||||
@@ -129,6 +133,36 @@ private:
|
||||
using SchemaNode::SchemaNode;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * @brief Class representing a schema definition of a `case` node.
|
||||
+ *
|
||||
+ * Wraps `lysc_node_case`.
|
||||
+ */
|
||||
+class LIBYANG_CPP_EXPORT Case : public SchemaNode {
|
||||
+public:
|
||||
+ friend SchemaNode;
|
||||
+ friend Choice;
|
||||
+
|
||||
+private:
|
||||
+ using SchemaNode::SchemaNode;
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * @brief Class representing a schema definition of a `choice` node.
|
||||
+ *
|
||||
+ * Wraps `lysc_node_choice`.
|
||||
+ */
|
||||
+class LIBYANG_CPP_EXPORT Choice : public SchemaNode {
|
||||
+public:
|
||||
+ bool isMandatory() const;
|
||||
+ std::vector<Case> cases() const;
|
||||
+ std::optional<Case> defaultCase() const;
|
||||
+ friend SchemaNode;
|
||||
+
|
||||
+private:
|
||||
+ using SchemaNode::SchemaNode;
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* @brief Class representing a schema definition of a `container` node.
|
||||
*/
|
||||
diff --git a/src/SchemaNode.cpp b/src/SchemaNode.cpp
|
||||
index bd20402..26b5099 100644
|
||||
--- a/src/SchemaNode.cpp
|
||||
+++ b/src/SchemaNode.cpp
|
||||
@@ -191,6 +191,32 @@ NodeType SchemaNode::nodeType() const
|
||||
return utils::toNodeType(m_node->nodetype);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * @brief Try to cast this SchemaNode to a Case node.
|
||||
+ * @throws Error If this node is not a case.
|
||||
+ */
|
||||
+Case SchemaNode::asCase() const
|
||||
+{
|
||||
+ if (nodeType() != NodeType::Case) {
|
||||
+ throw Error("Schema node is not a case: " + path());
|
||||
+ }
|
||||
+
|
||||
+ return Case{m_node, m_ctx};
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Try to cast this SchemaNode to a Choice node.
|
||||
+ * @throws Error If this node is not a choice.
|
||||
+ */
|
||||
+Choice SchemaNode::asChoice() const
|
||||
+{
|
||||
+ if (nodeType() != NodeType::Choice) {
|
||||
+ throw Error("Schema node is not a choice: " + path());
|
||||
+ }
|
||||
+
|
||||
+ return Choice{m_node, m_ctx};
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* @brief Try to cast this SchemaNode to a Container node.
|
||||
* @throws Error If this node is not a container.
|
||||
@@ -401,6 +427,48 @@ bool AnyDataAnyXML::isMandatory() const
|
||||
return m_node->flags & LYS_MAND_TRUE;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * @brief Checks whether this choice is mandatory.
|
||||
+ *
|
||||
+ * Wraps flag `LYS_MAND_TRUE`.
|
||||
+ */
|
||||
+bool Choice::isMandatory() const
|
||||
+{
|
||||
+ return m_node->flags & LYS_MAND_TRUE;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Retrieves the list of cases for this choice.
|
||||
+ *
|
||||
+ * Wraps `lysc_node_choice::cases`.
|
||||
+ */
|
||||
+std::vector<Case> Choice::cases() const
|
||||
+{
|
||||
+ auto choice = reinterpret_cast<const lysc_node_choice*>(m_node);
|
||||
+ auto cases = reinterpret_cast<lysc_node*>(choice->cases);
|
||||
+ std::vector<Case> res;
|
||||
+ lysc_node* elem;
|
||||
+ LY_LIST_FOR(cases, elem)
|
||||
+ {
|
||||
+ res.emplace_back(Case(elem, m_ctx));
|
||||
+ }
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Retrieves the default case for this choice.
|
||||
+ *
|
||||
+ * Wraps `lysc_node_choice::dflt`.
|
||||
+ */
|
||||
+std::optional<Case> Choice::defaultCase() const
|
||||
+{
|
||||
+ auto choice = reinterpret_cast<const lysc_node_choice*>(m_node);
|
||||
+ if (!choice->dflt) {
|
||||
+ return std::nullopt;
|
||||
+ }
|
||||
+ return Case{reinterpret_cast<lysc_node*>(choice->dflt), m_ctx};
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* @brief Checks whether this container is mandatory.
|
||||
*
|
||||
diff --git a/tests/context.cpp b/tests/context.cpp
|
||||
index 902faf6..5929b75 100644
|
||||
--- a/tests/context.cpp
|
||||
+++ b/tests/context.cpp
|
||||
@@ -709,33 +709,56 @@ TEST_CASE("context")
|
||||
auto mod = ctx_pp->parseModule(type_module, libyang::SchemaFormat::YANG);
|
||||
|
||||
REQUIRE(mod.printStr(libyang::SchemaOutputFormat::Tree) == R"(module: type_module
|
||||
- +--rw anydataBasic? anydata
|
||||
- +--rw anydataWithMandatoryChild anydata
|
||||
- +--rw anyxmlBasic? anyxml
|
||||
- +--rw anyxmlWithMandatoryChild anyxml
|
||||
- +--rw leafBinary? binary
|
||||
- +--rw leafBits? bits
|
||||
- +--rw leafEnum? enumeration
|
||||
- +--rw leafEnum2? enumeration
|
||||
- +--rw leafNumber? int32
|
||||
- +--rw leafRef? -> /custom-prefix:listAdvancedWithOneKey/lol
|
||||
- +--rw leafRefRelaxed? -> /custom-prefix:listAdvancedWithOneKey/lol
|
||||
- +--rw leafString? string
|
||||
- +--rw leafUnion? union
|
||||
- +--rw meal? identityref
|
||||
- +--ro leafWithConfigFalse? string
|
||||
- +--rw leafWithDefaultValue? string
|
||||
- +--rw leafWithDescription? string
|
||||
- +--rw leafWithMandatoryTrue string
|
||||
- x--rw leafWithStatusDeprecated? string
|
||||
- o--rw leafWithStatusObsolete? string
|
||||
- +--rw leafWithUnits? int32
|
||||
- +--rw iid-valid? instance-identifier
|
||||
- +--rw iid-relaxed? instance-identifier
|
||||
- +--rw leafListBasic* string
|
||||
- +--rw leafListWithDefault* int32
|
||||
- +--rw leafListWithMinMaxElements* int32
|
||||
- +--rw leafListWithUnits* int32
|
||||
+ +--rw anydataBasic? anydata
|
||||
+ +--rw anydataWithMandatoryChild anydata
|
||||
+ +--rw anyxmlBasic? anyxml
|
||||
+ +--rw anyxmlWithMandatoryChild anyxml
|
||||
+ +--rw choiceBasicContainer
|
||||
+ | +--rw (choiceBasic)?
|
||||
+ | +--:(case1)
|
||||
+ | | +--rw l? string
|
||||
+ | | +--rw ll* string
|
||||
+ | +--:(case2)
|
||||
+ | +--rw l2? string
|
||||
+ +--rw choiceWithMandatoryContainer
|
||||
+ | +--rw (choiceWithMandatory)
|
||||
+ | +--:(case3)
|
||||
+ | | +--rw l3? string
|
||||
+ | +--:(case4)
|
||||
+ | +--rw l4? string
|
||||
+ +--rw choiceWithDefaultContainer
|
||||
+ | +--rw (choiceWithDefault)?
|
||||
+ | +--:(case5)
|
||||
+ | | +--rw l5? string
|
||||
+ | +--:(case6)
|
||||
+ | +--rw l6? string
|
||||
+ +--rw implicitCaseContainer
|
||||
+ | +--rw (implicitCase)?
|
||||
+ | +--:(implicitLeaf)
|
||||
+ | +--rw implicitLeaf? string
|
||||
+ +--rw leafBinary? binary
|
||||
+ +--rw leafBits? bits
|
||||
+ +--rw leafEnum? enumeration
|
||||
+ +--rw leafEnum2? enumeration
|
||||
+ +--rw leafNumber? int32
|
||||
+ +--rw leafRef? -> /custom-prefix:listAdvancedWithOneKey/lol
|
||||
+ +--rw leafRefRelaxed? -> /custom-prefix:listAdvancedWithOneKey/lol
|
||||
+ +--rw leafString? string
|
||||
+ +--rw leafUnion? union
|
||||
+ +--rw meal? identityref
|
||||
+ +--ro leafWithConfigFalse? string
|
||||
+ +--rw leafWithDefaultValue? string
|
||||
+ +--rw leafWithDescription? string
|
||||
+ +--rw leafWithMandatoryTrue string
|
||||
+ x--rw leafWithStatusDeprecated? string
|
||||
+ o--rw leafWithStatusObsolete? string
|
||||
+ +--rw leafWithUnits? int32
|
||||
+ +--rw iid-valid? instance-identifier
|
||||
+ +--rw iid-relaxed? instance-identifier
|
||||
+ +--rw leafListBasic* string
|
||||
+ +--rw leafListWithDefault* int32
|
||||
+ +--rw leafListWithMinMaxElements* int32
|
||||
+ +--rw leafListWithUnits* int32
|
||||
+--rw listBasic* [primary-key]
|
||||
| +--rw primary-key string
|
||||
+--rw listAdvancedWithOneKey* [lol]
|
||||
diff --git a/tests/example_schema.hpp b/tests/example_schema.hpp
|
||||
index 2861b1a..ae3b4de 100644
|
||||
--- a/tests/example_schema.hpp
|
||||
+++ b/tests/example_schema.hpp
|
||||
@@ -390,6 +390,66 @@ module type_module {
|
||||
mandatory true;
|
||||
}
|
||||
|
||||
+ container choiceBasicContainer {
|
||||
+ choice choiceBasic {
|
||||
+ case case1 {
|
||||
+ leaf l {
|
||||
+ type string;
|
||||
+ }
|
||||
+ leaf-list ll {
|
||||
+ type string;
|
||||
+ ordered-by user;
|
||||
+ }
|
||||
+ }
|
||||
+ case case2 {
|
||||
+ leaf l2 {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ container choiceWithMandatoryContainer {
|
||||
+ choice choiceWithMandatory {
|
||||
+ mandatory true;
|
||||
+ case case3 {
|
||||
+ leaf l3 {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ case case4 {
|
||||
+ leaf l4 {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ container choiceWithDefaultContainer {
|
||||
+ choice choiceWithDefault {
|
||||
+ default case5;
|
||||
+ case case5 {
|
||||
+ leaf l5 {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ case case6 {
|
||||
+ leaf l6 {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ container implicitCaseContainer {
|
||||
+ choice implicitCase {
|
||||
+ leaf implicitLeaf {
|
||||
+ type string;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
leaf leafBinary {
|
||||
type binary;
|
||||
}
|
||||
diff --git a/tests/schema_node.cpp b/tests/schema_node.cpp
|
||||
index 80c7407..8d74bd2 100644
|
||||
--- a/tests/schema_node.cpp
|
||||
+++ b/tests/schema_node.cpp
|
||||
@@ -58,6 +58,9 @@ TEST_CASE("SchemaNode")
|
||||
],
|
||||
"type_module:anydataWithMandatoryChild": {"content": "test-string"},
|
||||
"type_module:anyxmlWithMandatoryChild": {"content": "test-string"},
|
||||
+ "type_module:choiceWithMandatoryContainer": {
|
||||
+ "l4": "test-string"
|
||||
+ },
|
||||
"type_module:containerWithMandatoryChild": {
|
||||
"leafWithMandatoryTrue": "test-string"
|
||||
},
|
||||
@@ -180,6 +183,10 @@ TEST_CASE("SchemaNode")
|
||||
"/type_module:anydataWithMandatoryChild",
|
||||
"/type_module:anyxmlBasic",
|
||||
"/type_module:anyxmlWithMandatoryChild",
|
||||
+ "/type_module:choiceBasicContainer",
|
||||
+ "/type_module:choiceWithMandatoryContainer",
|
||||
+ "/type_module:choiceWithDefaultContainer",
|
||||
+ "/type_module:implicitCaseContainer",
|
||||
"/type_module:leafBinary",
|
||||
"/type_module:leafBits",
|
||||
"/type_module:leafEnum",
|
||||
@@ -417,6 +424,71 @@ TEST_CASE("SchemaNode")
|
||||
REQUIRE(!ctx->findPath("/type_module:anyxmlBasic").asAnyDataAnyXML().isMandatory());
|
||||
}
|
||||
|
||||
+ DOCTEST_SUBCASE("Choice and Case")
|
||||
+ {
|
||||
+ std::string xpath;
|
||||
+ bool isMandatory = false;
|
||||
+ std::optional<std::string> defaultCase;
|
||||
+ std::vector<std::string> caseNames;
|
||||
+ std::optional<libyang::SchemaNode> root;
|
||||
+
|
||||
+ DOCTEST_SUBCASE("two cases with nothing fancy")
|
||||
+ {
|
||||
+ root = ctx->findPath("/type_module:choiceBasicContainer");
|
||||
+ caseNames = {"case1", "case2"};
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("mandatory choice") {
|
||||
+ root = ctx->findPath("/type_module:choiceWithMandatoryContainer");
|
||||
+ isMandatory = true;
|
||||
+ caseNames = {"case3", "case4"};
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("default choice") {
|
||||
+ root = ctx->findPath("/type_module:choiceWithDefaultContainer");
|
||||
+ defaultCase = "case5";
|
||||
+ caseNames = {"case5", "case6"};
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("implicit case") {
|
||||
+ root = ctx->findPath("/type_module:implicitCaseContainer");
|
||||
+ caseNames = {"implicitLeaf"};
|
||||
+ }
|
||||
+
|
||||
+ // For testing purposes, we have each choice in its own container. As choice and case are not directly instantiable,
|
||||
+ // we wrap them in a container to simplify the testing process. It allows us to simply address the choice by its
|
||||
+ // container and then get the choice from it. It also prevents polluting the test schema with unnecessary nodes
|
||||
+ // and isolates the choice from other nodes.
|
||||
+ auto container = root->asContainer();
|
||||
+ auto choice = container.immediateChildren().begin()->asChoice();
|
||||
+ REQUIRE(choice.isMandatory() == isMandatory);
|
||||
+ REQUIRE(!!choice.defaultCase() == !!defaultCase);
|
||||
+ if (defaultCase) {
|
||||
+ REQUIRE(choice.defaultCase()->name() == *defaultCase);
|
||||
+ }
|
||||
+ std::vector<std::string> actualCaseNames;
|
||||
+ for (const auto& case_ : choice.cases()) {
|
||||
+ actualCaseNames.push_back(case_.name());
|
||||
+ }
|
||||
+ REQUIRE(actualCaseNames == caseNames);
|
||||
+
|
||||
+ // Also test child node access for one arbitrary choice/case combination
|
||||
+ if (root->path() == "/type_module:choiceBasicContainer") {
|
||||
+ REQUIRE(choice.cases().size() == 2);
|
||||
+ auto case1 = choice.cases()[0];
|
||||
+ auto children = case1.immediateChildren();
|
||||
+ auto it = children.begin();
|
||||
+ REQUIRE(it->asLeaf().name() == "l");
|
||||
+ ++it;
|
||||
+ REQUIRE(it->asLeafList().name() == "ll");
|
||||
+
|
||||
+ auto case2 = choice.cases()[1];
|
||||
+ children = case2.immediateChildren();
|
||||
+ it = children.begin();
|
||||
+ REQUIRE(it->asLeaf().name() == "l2");
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
DOCTEST_SUBCASE("Container::isMandatory")
|
||||
{
|
||||
REQUIRE(ctx->findPath("/type_module:containerWithMandatoryChild").asContainer().isMandatory());
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
From a1acdc794facf8cbf113f73274ecebd5898c81a1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Tue, 17 Dec 2024 15:08:43 +0100
|
||||
Subject: [PATCH 7/8] Wrap lyd_change_term for changing the value for a
|
||||
terminal node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Previously, the code would require a newPath(...,
|
||||
libyang::CreationOptions::Update), which is quite a mouthful.
|
||||
|
||||
Change-Id: I8a908c0fdd3e48dda830819758522a511adedd3b
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
include/libyang-cpp/DataNode.hpp | 8 ++++++
|
||||
src/DataNode.cpp | 21 ++++++++++++++++
|
||||
tests/data_node.cpp | 42 ++++++++++++++++++++++++++------
|
||||
3 files changed, 63 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/libyang-cpp/DataNode.hpp b/include/libyang-cpp/DataNode.hpp
|
||||
index 2211415..851681b 100644
|
||||
--- a/include/libyang-cpp/DataNode.hpp
|
||||
+++ b/include/libyang-cpp/DataNode.hpp
|
||||
@@ -212,6 +212,14 @@ public:
|
||||
Value value() const;
|
||||
types::Type valueType() const;
|
||||
|
||||
+ /** @brief Was the value changed? */
|
||||
+ enum class ValueChange {
|
||||
+ Changed, /**< Yes, this is an actual change of the stored value */
|
||||
+ ExplicitNonDefault, /**< It still holds the default value, but it's been set explicitly now */
|
||||
+ EqualValueNotChanged, /**< No change, the previous value is the same as the new one, and it isn't an implicit default */
|
||||
+ };
|
||||
+ ValueChange changeValue(const std::string value);
|
||||
+
|
||||
private:
|
||||
using DataNode::DataNode;
|
||||
};
|
||||
diff --git a/src/DataNode.cpp b/src/DataNode.cpp
|
||||
index 2ef17f2..84591e5 100644
|
||||
--- a/src/DataNode.cpp
|
||||
+++ b/src/DataNode.cpp
|
||||
@@ -903,6 +903,27 @@ types::Type DataNodeTerm::valueType() const
|
||||
return impl(reinterpret_cast<const lyd_node_term*>(m_node)->value);
|
||||
}
|
||||
|
||||
+/** @short Change the term's value
|
||||
+ *
|
||||
+ * Wraps `lyd_change_term`.
|
||||
+ * */
|
||||
+DataNodeTerm::ValueChange DataNodeTerm::changeValue(const std::string value)
|
||||
+{
|
||||
+ auto ret = lyd_change_term(m_node, value.c_str());
|
||||
+
|
||||
+ switch (ret) {
|
||||
+ case LY_SUCCESS:
|
||||
+ return ValueChange::Changed;
|
||||
+ case LY_EEXIST:
|
||||
+ return ValueChange::ExplicitNonDefault;
|
||||
+ case LY_ENOT:
|
||||
+ return ValueChange::EqualValueNotChanged;
|
||||
+ default:
|
||||
+ throwIfError(ret, "DataNodeTerm::changeValue failed");
|
||||
+ __builtin_unreachable();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* @brief Returns a collection for iterating depth-first over the subtree this instance points to.
|
||||
*
|
||||
diff --git a/tests/data_node.cpp b/tests/data_node.cpp
|
||||
index 8a2610e..45fd6c1 100644
|
||||
--- a/tests/data_node.cpp
|
||||
+++ b/tests/data_node.cpp
|
||||
@@ -456,15 +456,41 @@ TEST_CASE("Data Node manipulation")
|
||||
REQUIRE(node.hasDefaultValue());
|
||||
REQUIRE(node.isImplicitDefault());
|
||||
|
||||
- data->newPath("/example-schema3:leafWithDefault", "not-default-value", libyang::CreationOptions::Update);
|
||||
- node = data->findPath("/example-schema3:leafWithDefault")->asTerm();
|
||||
- REQUIRE(!node.hasDefaultValue());
|
||||
- REQUIRE(!node.isImplicitDefault());
|
||||
+ DOCTEST_SUBCASE("newPath")
|
||||
+ {
|
||||
+ data->newPath("/example-schema3:leafWithDefault", "not-default-value", libyang::CreationOptions::Update);
|
||||
+ node = data->findPath("/example-schema3:leafWithDefault")->asTerm();
|
||||
+ REQUIRE(!node.hasDefaultValue());
|
||||
+ REQUIRE(!node.isImplicitDefault());
|
||||
|
||||
- data->newPath("/example-schema3:leafWithDefault", "AHOJ", libyang::CreationOptions::Update);
|
||||
- node = data->findPath("/example-schema3:leafWithDefault")->asTerm();
|
||||
- REQUIRE(node.hasDefaultValue());
|
||||
- REQUIRE(!node.isImplicitDefault());
|
||||
+ data->newPath("/example-schema3:leafWithDefault", "AHOJ", libyang::CreationOptions::Update);
|
||||
+ node = data->findPath("/example-schema3:leafWithDefault")->asTerm();
|
||||
+ REQUIRE(node.hasDefaultValue());
|
||||
+ REQUIRE(!node.isImplicitDefault());
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("changing values")
|
||||
+ {
|
||||
+ auto node = data->findPath("/example-schema3:leafWithDefault");
|
||||
+ REQUIRE(!!node);
|
||||
+ auto term = node->asTerm();
|
||||
+
|
||||
+ DOCTEST_SUBCASE("to an arbitrary value") {
|
||||
+ REQUIRE(term.changeValue("cau") == libyang::DataNodeTerm::ValueChange::Changed);
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("from an implicit default to an explicit default") {
|
||||
+ REQUIRE(term.changeValue("AHOJ") == libyang::DataNodeTerm::ValueChange::ExplicitNonDefault);
|
||||
+ REQUIRE(term.changeValue("AHOJ") == libyang::DataNodeTerm::ValueChange::EqualValueNotChanged);
|
||||
+ REQUIRE(term.changeValue("cau") == libyang::DataNodeTerm::ValueChange::Changed);
|
||||
+ REQUIRE(term.changeValue("cau") == libyang::DataNodeTerm::ValueChange::EqualValueNotChanged);
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("from an implicit default to something else") {
|
||||
+ REQUIRE(term.changeValue("cau") == libyang::DataNodeTerm::ValueChange::Changed);
|
||||
+ REQUIRE(term.changeValue("cau") == libyang::DataNodeTerm::ValueChange::EqualValueNotChanged);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("isTerm")
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 39c7530caa510144c17521278b721ba1e6d8ff40 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Pecka?= <tomas.pecka@cesnet.cz>
|
||||
Date: Thu, 9 Jan 2025 15:31:37 +0100
|
||||
Subject: [PATCH 8/8] upstream stopped reporting schema-mounts node
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Change-Id: I940769d38d56fcfda3e1408c92331fdb00c161e9
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
tests/context.cpp | 3 +--
|
||||
2 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 3d86809..732f52b 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -28,7 +28,7 @@ option(WITH_DOCS "Create and install internal documentation (needs Doxygen)" ${D
|
||||
option(BUILD_SHARED_LIBS "By default, shared libs are enabled. Turn off for a static build." ON)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
-pkg_check_modules(LIBYANG REQUIRED libyang>=3.4.2 IMPORTED_TARGET)
|
||||
+pkg_check_modules(LIBYANG REQUIRED libyang>=3.7.8 IMPORTED_TARGET)
|
||||
set(LIBYANG_CPP_PKG_VERSION "3")
|
||||
|
||||
# FIXME from gcc 14.1 on we should be able to use the calendar/time from libstdc++ and thus remove the date dependency
|
||||
diff --git a/tests/context.cpp b/tests/context.cpp
|
||||
index 5929b75..9d38fea 100644
|
||||
--- a/tests/context.cpp
|
||||
+++ b/tests/context.cpp
|
||||
@@ -509,8 +509,7 @@ TEST_CASE("context")
|
||||
"error-message": "hi"
|
||||
}
|
||||
]
|
||||
- },
|
||||
- "ietf-yang-schema-mount:schema-mounts": {}
|
||||
+ }
|
||||
}
|
||||
)");
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From f7307481fc4ca167592acf925136e5f8a51e2150 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kundrát <jan.kundrat@cesnet.cz>
|
||||
Date: Wed, 18 Dec 2024 17:26:15 +0100
|
||||
Subject: [PATCH] Update dependencies
|
||||
|
||||
Depends-on: https://gerrit.cesnet.cz/c/CzechLight/dependencies/+/8134
|
||||
Change-Id: Ib170aa61600ffb9089460247f762ff5a947dd6c6
|
||||
---
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 22bce32..5ae8062 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -74,7 +74,7 @@
|
||||
pkg_check_modules(nghttp2 REQUIRED IMPORTED_TARGET libnghttp2_asio>=0.0.90 libnghttp2)
|
||||
find_package(Boost REQUIRED CONFIG COMPONENTS system thread)
|
||||
|
||||
-pkg_check_modules(SYSREPO-CPP REQUIRED IMPORTED_TARGET sysrepo-cpp>=3)
|
||||
+pkg_check_modules(SYSREPO-CPP REQUIRED IMPORTED_TARGET sysrepo-cpp>=4)
|
||||
pkg_check_modules(LIBYANG-CPP REQUIRED IMPORTED_TARGET libyang-cpp>=3)
|
||||
pkg_check_modules(SYSTEMD IMPORTED_TARGET libsystemd)
|
||||
pkg_check_modules(PAM REQUIRED IMPORTED_TARGET pam)
|
||||
diff --git a/tests/restconf-writing.cpp b/tests/restconf-writing.cpp
|
||||
index 0932984..d37ab03 100644
|
||||
--- a/tests/restconf-writing.cpp
|
||||
+++ b/tests/restconf-writing.cpp
|
||||
@@ -772,7 +772,7 @@
|
||||
{
|
||||
"error-type": "protocol",
|
||||
"error-tag": "invalid-value",
|
||||
- "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"lst\" instance to insert next to not found. (SR_ERR_NOT_FOUND)\u000A Applying operation \"replace\" failed. (SR_ERR_NOT_FOUND)"
|
||||
+ "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"lst\" instance to insert next to not found. (SR_ERR_NOT_FOUND)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -855,7 +855,7 @@
|
||||
{
|
||||
"error-type": "protocol",
|
||||
"error-tag": "invalid-value",
|
||||
- "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"ll\" instance to insert next to not found. (SR_ERR_NOT_FOUND)\u000A Applying operation \"replace\" failed. (SR_ERR_NOT_FOUND)"
|
||||
+ "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"ll\" instance to insert next to not found. (SR_ERR_NOT_FOUND)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1560,7 +1560,7 @@
|
||||
{
|
||||
"error-type": "protocol",
|
||||
"error-tag": "invalid-value",
|
||||
- "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"lst\" instance to insert next to not found. (SR_ERR_NOT_FOUND)\u000A Applying operation \"create\" failed. (SR_ERR_NOT_FOUND)"
|
||||
+ "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"lst\" instance to insert next to not found. (SR_ERR_NOT_FOUND)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1626,7 +1626,7 @@
|
||||
{
|
||||
"error-type": "protocol",
|
||||
"error-tag": "invalid-value",
|
||||
- "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"ll\" instance to insert next to not found. (SR_ERR_NOT_FOUND)\u000A Applying operation \"create\" failed. (SR_ERR_NOT_FOUND)"
|
||||
+ "error-message": "Session::applyChanges: Couldn't apply changes: SR_ERR_NOT_FOUND\u000A Node \"ll\" instance to insert next to not found. (SR_ERR_NOT_FOUND)"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
From 23fa270a747c35d65aeeba691599ed6b21b501f0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Tue, 29 Oct 2024 15:15:52 +0100
|
||||
Subject: [PATCH 1/6] error handling changes in upstream sysrepo
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Upstream commit 396e331e4634a417420a71ad723567b42d75c443 removed these
|
||||
extra error entries.
|
||||
|
||||
Change-Id: Ifeda21194db7b7f7fdae8b6ae13c1e2d1f6b8d3d
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
tests/subscriptions.cpp | 16 ++++++----------
|
||||
2 files changed, 7 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index eb5f900..1eb625f 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -28,7 +28,7 @@ option(WITH_EXAMPLES "Build examples" ON)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBYANG_CPP REQUIRED libyang-cpp>=3 IMPORTED_TARGET)
|
||||
-pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.11.7 IMPORTED_TARGET)
|
||||
+pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.12.0 IMPORTED_TARGET)
|
||||
set(SYSREPO_CPP_PKG_VERSION "3")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
diff --git a/tests/subscriptions.cpp b/tests/subscriptions.cpp
|
||||
index 0e14fc0..36fd61c 100644
|
||||
--- a/tests/subscriptions.cpp
|
||||
+++ b/tests/subscriptions.cpp
|
||||
@@ -494,11 +494,11 @@ TEST_CASE("subscriptions")
|
||||
sess.applyChanges();
|
||||
} catch (const sysrepo::ErrorWithCode&) {
|
||||
auto errors = sess.getErrors();
|
||||
- REQUIRE(errors.size() == 2);
|
||||
- REQUIRE(errors.at(0).errorMessage == message);
|
||||
- REQUIRE(errors.at(0).code == sysrepo::ErrorCode::OperationFailed);
|
||||
- REQUIRE(errors.at(1).errorMessage == "User callback failed.");
|
||||
- REQUIRE(errors.at(1).code == sysrepo::ErrorCode::CallbackFailed);
|
||||
+ REQUIRE(errors.size() == 1);
|
||||
+ REQUIRE(errors.at(0) == sysrepo::ErrorInfo{
|
||||
+ .code = sysrepo::ErrorCode::OperationFailed,
|
||||
+ .errorMessage = message
|
||||
+ });
|
||||
}
|
||||
|
||||
// The callback does not fail the second time.
|
||||
@@ -548,15 +548,11 @@ TEST_CASE("subscriptions")
|
||||
sess.setItem("/test_module:leafInt32", "123");
|
||||
REQUIRE_THROWS_AS(sess.applyChanges(), sysrepo::ErrorWithCode);
|
||||
auto errors = sess.getErrors();
|
||||
- REQUIRE(errors.size() == 2);
|
||||
+ REQUIRE(errors.size() == 1);
|
||||
REQUIRE(errors.at(0) == sysrepo::ErrorInfo{
|
||||
.code = sysrepo::ErrorCode::OperationFailed,
|
||||
.errorMessage = "Test callback failure.",
|
||||
});
|
||||
- REQUIRE(errors.at(1) == sysrepo::ErrorInfo{
|
||||
- .code = sysrepo::ErrorCode::CallbackFailed,
|
||||
- .errorMessage = "User callback failed."
|
||||
- });
|
||||
auto ncErrors = sess.getNetconfErrors();
|
||||
REQUIRE(ncErrors.size() == 1);
|
||||
REQUIRE(ncErrors.front() == errToSet);
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From a73ffe1a5bbab51a67cf56dd2864c71a29c6685b Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Thu, 21 Nov 2024 11:18:25 +0100
|
||||
Subject: [PATCH 2/6] Fix error message when sr_session_start fails
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Thanks to Jason Patterson for sending a bugreport; its investigation led
|
||||
to discovering this bug.
|
||||
|
||||
See-also: https://github.com/CESNET/rousette/issues/15
|
||||
Change-Id: I082987d60380f860e08f26b436d0f9db4a231bec
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/Connection.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/Connection.cpp b/src/Connection.cpp
|
||||
index de65d64..716fd1a 100644
|
||||
--- a/src/Connection.cpp
|
||||
+++ b/src/Connection.cpp
|
||||
@@ -53,7 +53,7 @@ Session Connection::sessionStart(sysrepo::Datastore datastore)
|
||||
sr_session_ctx_t* sess;
|
||||
auto res = sr_session_start(ctx.get(), toDatastore(datastore), &sess);
|
||||
|
||||
- throwIfError(res, "Couldn't connect to sysrepo");
|
||||
+ throwIfError(res, "Couldn't start sysrepo session");
|
||||
return Session{sess, ctx};
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
From 552a366990fe1fe2cdd8d155fa5cecb3ff3fbc13 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Wed, 4 Dec 2024 15:51:41 +0100
|
||||
Subject: [PATCH 3/6] We don't support sysrepo v3 yet
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
That version introduced some backward-incompatible changes to the way
|
||||
how operational data are treated, especially in presence of "discards"
|
||||
of this data. It's a breaking behavior, and before we release a fix,
|
||||
let's pin the version to something which still works. The latest sysrepo
|
||||
semi-release is v 2.12.0, which is unfortunately not tagged.
|
||||
|
||||
Change-Id: I3673de9893d6e806926767a72b1ef83ee62bd610
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
.zuul.yaml | 4 ++--
|
||||
CMakeLists.txt | 2 +-
|
||||
README.md | 1 +
|
||||
3 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/.zuul.yaml b/.zuul.yaml
|
||||
index dc87c6f..c3aea22 100644
|
||||
--- a/.zuul.yaml
|
||||
+++ b/.zuul.yaml
|
||||
@@ -6,7 +6,7 @@
|
||||
- name: github/CESNET/libyang
|
||||
override-checkout: devel
|
||||
- name: github/sysrepo/sysrepo
|
||||
- override-checkout: devel
|
||||
+ override-checkout: cesnet/2024-10-before-oper-changes
|
||||
- name: github/onqtam/doctest
|
||||
override-checkout: v2.4.8
|
||||
- name: github/rollbear/trompeloeil
|
||||
@@ -17,7 +17,7 @@
|
||||
- name: github/CESNET/libyang
|
||||
override-checkout: devel
|
||||
- name: github/sysrepo/sysrepo
|
||||
- override-checkout: devel
|
||||
+ override-checkout: cesnet/2024-10-before-oper-changes
|
||||
- name: github/onqtam/doctest
|
||||
override-checkout: v2.4.11
|
||||
- name: github/rollbear/trompeloeil
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 1eb625f..119bdd7 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -28,7 +28,7 @@ option(WITH_EXAMPLES "Build examples" ON)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBYANG_CPP REQUIRED libyang-cpp>=3 IMPORTED_TARGET)
|
||||
-pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.12.0 IMPORTED_TARGET)
|
||||
+pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.12.0 sysrepo<3 IMPORTED_TARGET)
|
||||
set(SYSREPO_CPP_PKG_VERSION "3")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
diff --git a/README.md b/README.md
|
||||
index 27dc748..e14b772 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -9,6 +9,7 @@ It uses RAII for automatic memory management.
|
||||
|
||||
## Dependencies
|
||||
- [sysrepo](https://github.com/sysrepo/sysrepo) - the `devel` branch (even for the `master` branch of *sysrepo-cpp*)
|
||||
+ - we temporarily require pre-v3 sysrepo which introduced backward-incompatible changes to operational data handling
|
||||
- [libyang-cpp](https://github.com/CESNET/libyang-cpp) - C++ bindings for *libyang*
|
||||
- C++20 compiler (e.g., GCC 10.x+, clang 10+)
|
||||
- CMake 3.19+
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From f2db30721d909d127645721f4149de0cd36d2b1c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Tue, 17 Dec 2024 11:41:10 +0100
|
||||
Subject: [PATCH 4/6] refactor: don't use `module` as a variable name
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
...to unify stuff with all other occurrences, and to not use that magic
|
||||
identifier.
|
||||
|
||||
Change-Id: I8c38777a925271e7659560d0380a7f7968f4cfa7
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
include/sysrepo-cpp/Session.hpp | 4 ++--
|
||||
src/Session.cpp | 12 ++++++------
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/sysrepo-cpp/Session.hpp b/include/sysrepo-cpp/Session.hpp
|
||||
index 7da11cb..477e604 100644
|
||||
--- a/include/sysrepo-cpp/Session.hpp
|
||||
+++ b/include/sysrepo-cpp/Session.hpp
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
void copyConfig(const Datastore source, const std::optional<std::string>& moduleName = std::nullopt, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
libyang::DataNode sendRPC(libyang::DataNode input, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
void sendNotification(libyang::DataNode notification, const Wait wait, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
- void replaceConfig(std::optional<libyang::DataNode> config, const std::optional<std::string>& module = std::nullopt, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
+ void replaceConfig(std::optional<libyang::DataNode> config, const std::optional<std::string>& moduleName = std::nullopt, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
|
||||
void setNacmUser(const std::string& user);
|
||||
[[nodiscard]] Subscription initNacm(
|
||||
@@ -172,7 +172,7 @@ public:
|
||||
*
|
||||
* Wraps `sr_lock`.
|
||||
*/
|
||||
- explicit Lock(Session session, std::optional<std::string> module = std::nullopt, std::optional<std::chrono::milliseconds> timeout = std::nullopt);
|
||||
+ explicit Lock(Session session, std::optional<std::string> moduleName = std::nullopt, std::optional<std::chrono::milliseconds> timeout = std::nullopt);
|
||||
/** @brief Release the lock
|
||||
*
|
||||
* Wraps `sr_unlock`.
|
||||
diff --git a/src/Session.cpp b/src/Session.cpp
|
||||
index 2706e1c..94a0fad 100644
|
||||
--- a/src/Session.cpp
|
||||
+++ b/src/Session.cpp
|
||||
@@ -331,17 +331,17 @@ void Session::sendNotification(libyang::DataNode notification, const Wait wait,
|
||||
* Wraps `sr_replace_config`.
|
||||
*
|
||||
* @param config Libyang tree to use as a complete datastore content, or nullopt
|
||||
- * @param module If provided, a module name to limit the operation to
|
||||
+ * @param moduleName If provided, a module name to limit the operation to
|
||||
* @param timeout Optional timeout to wait for
|
||||
*/
|
||||
-void Session::replaceConfig(std::optional<libyang::DataNode> config, const std::optional<std::string>& module, std::chrono::milliseconds timeout)
|
||||
+void Session::replaceConfig(std::optional<libyang::DataNode> config, const std::optional<std::string>& moduleName, std::chrono::milliseconds timeout)
|
||||
{
|
||||
std::optional<libyang::DataNode> thrashable;
|
||||
if (config) {
|
||||
thrashable = config->duplicateWithSiblings(libyang::DuplicationOptions::Recursive | libyang::DuplicationOptions::WithParents);
|
||||
}
|
||||
auto res = sr_replace_config(
|
||||
- m_sess.get(), module ? module->c_str() : nullptr,
|
||||
+ m_sess.get(), moduleName ? moduleName->c_str() : nullptr,
|
||||
config ? libyang::releaseRawNode(*thrashable) : nullptr,
|
||||
timeout.count());
|
||||
throwIfError(res, "sr_replace_config failed", m_sess.get());
|
||||
@@ -723,12 +723,12 @@ uint32_t Session::getId() const
|
||||
return sr_session_get_id(m_sess.get());
|
||||
}
|
||||
|
||||
-Lock::Lock(Session session, std::optional<std::string> module, std::optional<std::chrono::milliseconds> timeout)
|
||||
+Lock::Lock(Session session, std::optional<std::string> moduleName, std::optional<std::chrono::milliseconds> timeout)
|
||||
: m_session(session)
|
||||
, m_lockedDs(m_session.activeDatastore())
|
||||
- , m_module(module)
|
||||
+ , m_module(moduleName)
|
||||
{
|
||||
- auto res = sr_lock(getRawSession(m_session), module ? module->c_str() : nullptr, timeout ? timeout->count() : 0);
|
||||
+ auto res = sr_lock(getRawSession(m_session), moduleName ? moduleName->c_str() : nullptr, timeout ? timeout->count() : 0);
|
||||
throwIfError(res, "Cannot lock session", getRawSession(m_session));
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
From a923f490350dc61b9f3e6000c06c1d7950a78a61 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Wed, 18 Dec 2024 16:12:14 +0100
|
||||
Subject: [PATCH 5/6] DRY: a dummy leaf XPath
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Change-Id: I47fca61d27380af07b2327f3ee5b984a8a8afb66
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
tests/session.cpp | 81 ++++++++++++++++++++++++-----------------------
|
||||
1 file changed, 41 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/tests/session.cpp b/tests/session.cpp
|
||||
index 5b384bb..f762f10 100644
|
||||
--- a/tests/session.cpp
|
||||
+++ b/tests/session.cpp
|
||||
@@ -20,6 +20,7 @@ TEST_CASE("session")
|
||||
std::optional<sysrepo::Connection> conn{std::in_place};
|
||||
auto sess = conn->sessionStart();
|
||||
sess.copyConfig(sysrepo::Datastore::Startup);
|
||||
+ const auto leaf = "/test_module:leafInt32"s;
|
||||
|
||||
DOCTEST_SUBCASE("Session should be still valid even after the Connection class gets freed")
|
||||
{
|
||||
@@ -29,39 +30,39 @@ TEST_CASE("session")
|
||||
|
||||
DOCTEST_SUBCASE("Session lifetime is prolonged with data from getData")
|
||||
{
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
+ sess.setItem(leaf, "123");
|
||||
sess.applyChanges();
|
||||
- auto data = sysrepo::Connection{}.sessionStart().getData("/test_module:leafInt32");
|
||||
+ auto data = sysrepo::Connection{}.sessionStart().getData(leaf);
|
||||
REQUIRE(data->asTerm().valueStr() == "123");
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("basic data manipulation")
|
||||
{
|
||||
- auto data = sess.getData("/test_module:leafInt32");
|
||||
+ auto data = sess.getData(leaf);
|
||||
REQUIRE(!data);
|
||||
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
+ sess.setItem(leaf, "123");
|
||||
sess.applyChanges();
|
||||
- data = sess.getData("/test_module:leafInt32");
|
||||
+ data = sess.getData(leaf);
|
||||
REQUIRE(data->asTerm().valueStr() == "123");
|
||||
- auto node = sess.getOneNode("/test_module:leafInt32");
|
||||
+ auto node = sess.getOneNode(leaf);
|
||||
REQUIRE(node.asTerm().valueStr() == "123");
|
||||
|
||||
- sess.setItem("/test_module:leafInt32", "420");
|
||||
+ sess.setItem(leaf, "420");
|
||||
sess.applyChanges();
|
||||
- data = sess.getData("/test_module:leafInt32");
|
||||
+ data = sess.getData(leaf);
|
||||
REQUIRE(data->asTerm().valueStr() == "420");
|
||||
|
||||
- sess.deleteItem("/test_module:leafInt32");
|
||||
+ sess.deleteItem(leaf);
|
||||
sess.applyChanges();
|
||||
- data = sess.getData("/test_module:leafInt32");
|
||||
+ data = sess.getData(leaf);
|
||||
REQUIRE(!data);
|
||||
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
+ sess.setItem(leaf, "123");
|
||||
sess.discardChanges();
|
||||
- data = sess.getData("/test_module:leafInt32");
|
||||
+ data = sess.getData(leaf);
|
||||
REQUIRE(!data);
|
||||
- REQUIRE_THROWS_WITH_AS(sess.getOneNode("/test_module:leafInt32"),
|
||||
+ REQUIRE_THROWS_WITH_AS(sess.getOneNode(leaf),
|
||||
"Session::getOneNode: Couldn't get '/test_module:leafInt32': SR_ERR_NOT_FOUND",
|
||||
sysrepo::ErrorWithCode);
|
||||
|
||||
@@ -175,7 +176,7 @@ TEST_CASE("session")
|
||||
{
|
||||
sess.switchDatastore(sysrepo::Datastore::Operational);
|
||||
sess.setItem("/test_module:stateLeaf", "42");
|
||||
- sess.setItem("/test_module:leafInt32", "1");
|
||||
+ sess.setItem(leaf, "1");
|
||||
sess.applyChanges();
|
||||
|
||||
DOCTEST_SUBCASE("Default options")
|
||||
@@ -183,7 +184,7 @@ TEST_CASE("session")
|
||||
auto data = sess.getData("/test_module:*");
|
||||
REQUIRE(data);
|
||||
REQUIRE(data->findPath("/test_module:stateLeaf"));
|
||||
- REQUIRE(data->findPath("/test_module:leafInt32"));
|
||||
+ REQUIRE(data->findPath(leaf));
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("No state data")
|
||||
@@ -191,7 +192,7 @@ TEST_CASE("session")
|
||||
auto data = sess.getData("/test_module:*", 0, sysrepo::GetOptions::OperNoState);
|
||||
REQUIRE(data);
|
||||
REQUIRE(!data->findPath("/test_module:stateLeaf"));
|
||||
- REQUIRE(data->findPath("/test_module:leafInt32"));
|
||||
+ REQUIRE(data->findPath(leaf));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,42 +214,42 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("Session::deleteOperItem")
|
||||
{
|
||||
// Set some arbitrary leaf.
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
+ sess.setItem(leaf, "123");
|
||||
sess.applyChanges();
|
||||
|
||||
// The leaf is accesible from the running datastore.
|
||||
- REQUIRE(sess.getData("/test_module:leafInt32")->asTerm().valueStr() == "123");
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
|
||||
// The leaf is NOT accesible from the operational datastore without a subscription.
|
||||
sess.switchDatastore(sysrepo::Datastore::Operational);
|
||||
- REQUIRE(!sess.getData("/test_module:leafInt32"));
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
|
||||
// When we create a subscription, the leaf is accesible from the operational datastore.
|
||||
sess.switchDatastore(sysrepo::Datastore::Running);
|
||||
auto sub = sess.onModuleChange("test_module", [] (auto, auto, auto, auto, auto, auto) { return sysrepo::ErrorCode::Ok; });
|
||||
sess.switchDatastore(sysrepo::Datastore::Operational);
|
||||
- REQUIRE(sess.getData("/test_module:leafInt32")->asTerm().valueStr() == "123");
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
|
||||
// After using deleteItem, the leaf is no longer accesible from the operational datastore.
|
||||
- sess.deleteItem("/test_module:leafInt32");
|
||||
+ sess.deleteItem(leaf);
|
||||
sess.applyChanges();
|
||||
- REQUIRE(!sess.getData("/test_module:leafInt32"));
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
|
||||
// Using discardItems makes the leaf visible again (in the operational datastore).
|
||||
- sess.discardItems("/test_module:leafInt32");
|
||||
+ sess.discardItems(leaf);
|
||||
sess.applyChanges();
|
||||
- REQUIRE(sess.getData("/test_module:leafInt32")->asTerm().valueStr() == "123");
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("edit batch")
|
||||
{
|
||||
- auto data = sess.getData("/test_module:leafInt32");
|
||||
+ auto data = sess.getData(leaf);
|
||||
REQUIRE(!data);
|
||||
|
||||
- auto batch = sess.getContext().newPath("/test_module:leafInt32", "1230");
|
||||
+ auto batch = sess.getContext().newPath(leaf, "1230");
|
||||
sess.editBatch(batch, sysrepo::DefaultOperation::Merge);
|
||||
sess.applyChanges();
|
||||
- data = sess.getData("/test_module:leafInt32");
|
||||
+ data = sess.getData(leaf);
|
||||
REQUIRE(data->asTerm().valueStr() == "1230");
|
||||
}
|
||||
|
||||
@@ -307,8 +308,8 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("Session::getPendingChanges")
|
||||
{
|
||||
REQUIRE(sess.getPendingChanges() == std::nullopt);
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
- REQUIRE(sess.getPendingChanges().value().findPath("/test_module:leafInt32")->asTerm().valueStr() == "123");
|
||||
+ sess.setItem(leaf, "123");
|
||||
+ REQUIRE(sess.getPendingChanges().value().findPath(leaf)->asTerm().valueStr() == "123");
|
||||
|
||||
DOCTEST_SUBCASE("apply")
|
||||
{
|
||||
@@ -328,7 +329,7 @@ TEST_CASE("session")
|
||||
sess.switchDatastore(sysrepo::Datastore::FactoryDefault);
|
||||
auto data = sess.getData("/*");
|
||||
REQUIRE(*data->printStr(libyang::DataFormat::JSON, libyang::PrintFlags::WithSiblings) == "{\n\n}\n");
|
||||
- REQUIRE_THROWS_AS(sess.setItem("/test_module:leafInt32", "123"), sysrepo::ErrorWithCode);
|
||||
+ REQUIRE_THROWS_AS(sess.setItem(leaf, "123"), sysrepo::ErrorWithCode);
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("session IDs")
|
||||
@@ -391,9 +392,9 @@ TEST_CASE("session")
|
||||
|
||||
DOCTEST_SUBCASE("replace config")
|
||||
{
|
||||
- REQUIRE(!sess.getData("/test_module:leafInt32"));
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
// some "reasonable data" for two modules
|
||||
- sess.setItem("/test_module:leafInt32", "666");
|
||||
+ sess.setItem(leaf, "666");
|
||||
sess.setItem("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']", "");
|
||||
sess.applyChanges();
|
||||
|
||||
@@ -401,16 +402,16 @@ TEST_CASE("session")
|
||||
REQUIRE(!!conf);
|
||||
|
||||
// override a single leaf
|
||||
- REQUIRE(sess.getOneNode("/test_module:leafInt32").asTerm().valueStr() == "666");
|
||||
- sess.setItem("/test_module:leafInt32", "123");
|
||||
+ REQUIRE(sess.getOneNode(leaf).asTerm().valueStr() == "666");
|
||||
+ sess.setItem(leaf, "123");
|
||||
sess.setItem("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']", "");
|
||||
sess.applyChanges();
|
||||
- REQUIRE(sess.getOneNode("/test_module:leafInt32").asTerm().valueStr() == "123");
|
||||
+ REQUIRE(sess.getOneNode(leaf).asTerm().valueStr() == "123");
|
||||
|
||||
DOCTEST_SUBCASE("this module empty config")
|
||||
{
|
||||
sess.replaceConfig(std::nullopt, "test_module");
|
||||
- REQUIRE(!sess.getData("/test_module:leafInt32"));
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
REQUIRE(sess.getOneNode("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']").asTerm().valueStr() == "foo");
|
||||
REQUIRE(sess.getOneNode("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']").asTerm().valueStr() == "bar");
|
||||
}
|
||||
@@ -418,7 +419,7 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("this module")
|
||||
{
|
||||
sess.replaceConfig(conf, "test_module");
|
||||
- REQUIRE(sess.getOneNode("/test_module:leafInt32").asTerm().valueStr() == "666");
|
||||
+ REQUIRE(sess.getOneNode(leaf).asTerm().valueStr() == "666");
|
||||
REQUIRE(sess.getOneNode("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']").asTerm().valueStr() == "foo");
|
||||
REQUIRE(sess.getOneNode("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']").asTerm().valueStr() == "bar");
|
||||
}
|
||||
@@ -426,7 +427,7 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("other module")
|
||||
{
|
||||
sess.replaceConfig(std::nullopt, "ietf-netconf-acm");
|
||||
- REQUIRE(sess.getOneNode("/test_module:leafInt32").asTerm().valueStr() == "123");
|
||||
+ REQUIRE(sess.getOneNode(leaf).asTerm().valueStr() == "123");
|
||||
REQUIRE(!sess.getData("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']"));
|
||||
REQUIRE(!sess.getData("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']"));
|
||||
}
|
||||
@@ -434,7 +435,7 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("entire datastore empty config")
|
||||
{
|
||||
sess.replaceConfig(std::nullopt);
|
||||
- REQUIRE(!sess.getData("/test_module:leafInt32"));
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
REQUIRE(!sess.getData("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']"));
|
||||
REQUIRE(!sess.getData("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']"));
|
||||
}
|
||||
@@ -442,7 +443,7 @@ TEST_CASE("session")
|
||||
DOCTEST_SUBCASE("entire datastore")
|
||||
{
|
||||
sess.replaceConfig(conf);
|
||||
- REQUIRE(sess.getOneNode("/test_module:leafInt32").asTerm().valueStr() == "666");
|
||||
+ REQUIRE(sess.getOneNode(leaf).asTerm().valueStr() == "666");
|
||||
REQUIRE(sess.getOneNode("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='foo']").asTerm().valueStr() == "foo");
|
||||
REQUIRE(!sess.getData("/ietf-netconf-acm:nacm/groups/group[name='ahoj']/user-name[.='bar']"));
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
From 80e9659b41ea1de2e20d62f94319fe5af26adcee Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Jan=20Kundr=C3=A1t?= <jan.kundrat@cesnet.cz>
|
||||
Date: Wed, 18 Dec 2024 17:57:36 +0100
|
||||
Subject: [PATCH 6/6] build: a single place to define package version
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Don't ask me how I found out that I need this :).
|
||||
|
||||
Change-Id: I2cd7397895ed4852f852e99b97543dde76eaff8f
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 119bdd7..68ade53 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -20,7 +20,8 @@ add_custom_target(sysrepo-cpp-version-cmake
|
||||
cmake/ProjectGitVersionRunner.cmake
|
||||
)
|
||||
include(cmake/ProjectGitVersion.cmake)
|
||||
-prepare_git_version(SYSREPO_CPP_VERSION "3")
|
||||
+set(SYSREPO_CPP_PKG_VERSION "3")
|
||||
+prepare_git_version(SYSREPO_CPP_VERSION ${SYSREPO_CPP_PKG_VERSION})
|
||||
|
||||
find_package(Doxygen)
|
||||
option(WITH_DOCS "Create and install internal documentation (needs Doxygen)" ${DOXYGEN_FOUND})
|
||||
@@ -29,7 +30,6 @@ option(WITH_EXAMPLES "Build examples" ON)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBYANG_CPP REQUIRED libyang-cpp>=3 IMPORTED_TARGET)
|
||||
pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.12.0 sysrepo<3 IMPORTED_TARGET)
|
||||
-set(SYSREPO_CPP_PKG_VERSION "3")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,342 @@
|
||||
From b34fb200812f9e6bc72e80bf46bd006ebc06a9da Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kundrát <jan.kundrat@cesnet.cz>
|
||||
Date: Wed, 18 Dec 2024 17:16:55 +0100
|
||||
Subject: [PATCH] API/ABI break: Change how pushed ops data work
|
||||
|
||||
Upstream has changed the way how pushed operational data are stored and
|
||||
managed. From now on, each session has a separate edit, these edits are
|
||||
applied on top of each other using a given priority (priority setting is
|
||||
not implemented in the C++ wrapper at this time, patches welcome). Each
|
||||
session can retrieve and manipulate the stored edit.
|
||||
|
||||
The key difference is that these edits are now per-session. This has a
|
||||
wide-ranging impact, and the way how previously set nodes are "undone"
|
||||
has changed. Unfortunately, upstream refused to rename the relevant
|
||||
functions due to "API stability concerns", so we're taking care of
|
||||
avoiding the possible confusion at the C++ layer:
|
||||
|
||||
- `Session::dropForeignOperationalContent` (aka `sr_discard_items`),
|
||||
which is now used to ensure that matching content from "previous
|
||||
sources" is discarded. These "previous sources" are either content of
|
||||
`running`, or stuff that was stored/pushed by other sessions with
|
||||
lower priority. It *cannot* be used to remove stuff that was
|
||||
previously pushed by the current session.
|
||||
|
||||
- `Session::discardOperationalChanges` (aka `sr_discard_oper_changes`)
|
||||
discards previously pushed content from *this session*.
|
||||
|
||||
- It is now possible to fully manage the edit (which incrementally
|
||||
builds the `operational` DS) of the current session. Use
|
||||
`Session::operationalChanges()` to retrieve a full libyang::DataNode
|
||||
forest, modify it in whichever ways are needed, and store it back via
|
||||
`Session::editBatch(..., sysrepo::DefaultOperation::Replace)` followed
|
||||
by `Session::applyChanges()`.
|
||||
|
||||
Change-Id: Iba05a88411fd4c47c03d8c2b48cb7aadfd5dcd2a
|
||||
---
|
||||
|
||||
diff --git a/.zuul.yaml b/.zuul.yaml
|
||||
index c3aea22..dc87c6f 100644
|
||||
--- a/.zuul.yaml
|
||||
+++ b/.zuul.yaml
|
||||
@@ -6,7 +6,7 @@
|
||||
- name: github/CESNET/libyang
|
||||
override-checkout: devel
|
||||
- name: github/sysrepo/sysrepo
|
||||
- override-checkout: cesnet/2024-10-before-oper-changes
|
||||
+ override-checkout: devel
|
||||
- name: github/onqtam/doctest
|
||||
override-checkout: v2.4.8
|
||||
- name: github/rollbear/trompeloeil
|
||||
@@ -17,7 +17,7 @@
|
||||
- name: github/CESNET/libyang
|
||||
override-checkout: devel
|
||||
- name: github/sysrepo/sysrepo
|
||||
- override-checkout: cesnet/2024-10-before-oper-changes
|
||||
+ override-checkout: devel
|
||||
- name: github/onqtam/doctest
|
||||
override-checkout: v2.4.11
|
||||
- name: github/rollbear/trompeloeil
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 68ade53..cc4dba9 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -20,7 +20,7 @@
|
||||
cmake/ProjectGitVersionRunner.cmake
|
||||
)
|
||||
include(cmake/ProjectGitVersion.cmake)
|
||||
-set(SYSREPO_CPP_PKG_VERSION "3")
|
||||
+set(SYSREPO_CPP_PKG_VERSION "4")
|
||||
prepare_git_version(SYSREPO_CPP_VERSION ${SYSREPO_CPP_PKG_VERSION})
|
||||
|
||||
find_package(Doxygen)
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(LIBYANG_CPP REQUIRED libyang-cpp>=3 IMPORTED_TARGET)
|
||||
-pkg_check_modules(SYSREPO REQUIRED sysrepo>=2.12.0 sysrepo<3 IMPORTED_TARGET)
|
||||
+pkg_check_modules(SYSREPO REQUIRED sysrepo>=3.4.0 IMPORTED_TARGET)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
diff --git a/README.md b/README.md
|
||||
index e14b772..27dc748 100644
|
||||
--- a/README.md
|
||||
+++ b/README.md
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
## Dependencies
|
||||
- [sysrepo](https://github.com/sysrepo/sysrepo) - the `devel` branch (even for the `master` branch of *sysrepo-cpp*)
|
||||
- - we temporarily require pre-v3 sysrepo which introduced backward-incompatible changes to operational data handling
|
||||
- [libyang-cpp](https://github.com/CESNET/libyang-cpp) - C++ bindings for *libyang*
|
||||
- C++20 compiler (e.g., GCC 10.x+, clang 10+)
|
||||
- CMake 3.19+
|
||||
diff --git a/include/sysrepo-cpp/Session.hpp b/include/sysrepo-cpp/Session.hpp
|
||||
index 477e604..238f480 100644
|
||||
--- a/include/sysrepo-cpp/Session.hpp
|
||||
+++ b/include/sysrepo-cpp/Session.hpp
|
||||
@@ -85,13 +85,15 @@
|
||||
void setItem(const std::string& path, const std::optional<std::string>& value, const EditOptions opts = sysrepo::EditOptions::Default);
|
||||
void editBatch(libyang::DataNode edit, const DefaultOperation op);
|
||||
void deleteItem(const std::string& path, const EditOptions opts = sysrepo::EditOptions::Default);
|
||||
- void discardItems(const std::optional<std::string>& xpath);
|
||||
void moveItem(const std::string& path, const MovePosition move, const std::optional<std::string>& keys_or_value, const std::optional<std::string>& origin = std::nullopt, const EditOptions opts = sysrepo::EditOptions::Default);
|
||||
std::optional<libyang::DataNode> getData(const std::string& path, int maxDepth = 0, const GetOptions opts = sysrepo::GetOptions::Default, std::chrono::milliseconds timeout = std::chrono::milliseconds{0}) const;
|
||||
libyang::DataNode getOneNode(const std::string& path, std::chrono::milliseconds timeout = std::chrono::milliseconds{0}) const;
|
||||
std::optional<const libyang::DataNode> getPendingChanges() const;
|
||||
void applyChanges(std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
- void discardChanges();
|
||||
+ void discardChanges(const std::optional<std::string>& xpath = std::nullopt);
|
||||
+ std::optional<libyang::DataNode> operationalChanges(const std::optional<std::string>& moduleName = std::nullopt) const;
|
||||
+ void discardOperationalChanges(const std::optional<std::string>& moduleName = std::nullopt, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
+ void dropForeignOperationalContent(const std::optional<std::string>& xpath);
|
||||
void copyConfig(const Datastore source, const std::optional<std::string>& moduleName = std::nullopt, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
libyang::DataNode sendRPC(libyang::DataNode input, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
void sendNotification(libyang::DataNode notification, const Wait wait, std::chrono::milliseconds timeout = std::chrono::milliseconds{0});
|
||||
diff --git a/src/Session.cpp b/src/Session.cpp
|
||||
index 94a0fad..634e450 100644
|
||||
--- a/src/Session.cpp
|
||||
+++ b/src/Session.cpp
|
||||
@@ -23,6 +23,26 @@
|
||||
|
||||
using namespace std::string_literals;
|
||||
namespace sysrepo {
|
||||
+
|
||||
+namespace {
|
||||
+libyang::DataNode wrapSrData(std::shared_ptr<sr_session_ctx_s> sess, sr_data_t* data)
|
||||
+{
|
||||
+ // Since the lyd_node came from sysrepo and it is wrapped in a sr_data_t, we have to postpone calling the
|
||||
+ // sr_release_data() until after we're "done" with the libyang::DataNode.
|
||||
+ //
|
||||
+ // Normally, sr_release_data() would free the lyd_data as well. However, it is possible that the user wants to
|
||||
+ // manipulate the data tree (think unlink()) in a way which might have needed to overwrite the tree->data pointer.
|
||||
+ // Just delegate all the freeing to the C++ wrapper around lyd_data. The sysrepo library doesn't care about this.
|
||||
+ auto tree = std::exchange(data->tree, nullptr);
|
||||
+
|
||||
+ // Use wrapRawNode, not wrapUnmanagedRawNode because we want to let the C++ wrapper manage memory.
|
||||
+ // Note: We're capturing the session inside the lambda.
|
||||
+ return libyang::wrapRawNode(tree, std::shared_ptr<sr_data_t>(data, [extend_session_lifetime = sess] (sr_data_t* data) {
|
||||
+ sr_release_data(data);
|
||||
+ }));
|
||||
+}
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Wraps a pointer to sr_session_ctx_s and manages the lifetime of it. Also extends the lifetime of the connection
|
||||
* specified by the `conn` argument.
|
||||
@@ -119,20 +139,61 @@
|
||||
}
|
||||
|
||||
/**
|
||||
- * Prepare to discard nodes matching the specified xpath (or all if not set) previously set by the session connection.
|
||||
- * Usable only for sysrepo::Datastore::Operational. The changes are applied only after calling Session::applyChanges.
|
||||
+ * Prepare to drop "earlier content" from other sources in the operational DS for nodes matching the specified XPath
|
||||
+ *
|
||||
+ * The "earlier content" might come from the `running` datastore, or be pushed into the `operational` DS from
|
||||
+ * another session, with a lower priority. This function prepares a special node into the current session's
|
||||
+ * stored edit which effectively discards any matching content from previous, lower-priority sources.
|
||||
+ *
|
||||
+ * This function cannot be used to remove an edit which was pushed via the current session. To do that,
|
||||
+ * use discardChanges(), or retrieve the stored edit and manipulate its libyang data tree.
|
||||
+ *
|
||||
+ * The changes are applied only after calling Session::applyChanges.
|
||||
*
|
||||
* Wraps `sr_discard_items`.
|
||||
*
|
||||
* @param xpath Expression filtering the nodes to discard, nullopt for all nodes.
|
||||
*/
|
||||
-void Session::discardItems(const std::optional<std::string>& xpath)
|
||||
+void Session::dropForeignOperationalContent(const std::optional<std::string>& xpath)
|
||||
{
|
||||
auto res = sr_discard_items(m_sess.get(), xpath ? xpath->c_str() : nullptr);
|
||||
|
||||
throwIfError(res, "Session::discardItems: Can't discard "s + (xpath ? "'"s + *xpath + "'" : "all nodes"s), m_sess.get());
|
||||
}
|
||||
|
||||
+/** @short Get a copy of the stored push-operational data for this session
|
||||
+ *
|
||||
+ * To modify the stored push operational data, modify this tree in-place and pass it to editBatch()
|
||||
+ * with the "replace" operation.
|
||||
+ *
|
||||
+ * Wraps `sr_get_oper_changes`.
|
||||
+ */
|
||||
+std::optional<libyang::DataNode> Session::operationalChanges(const std::optional<std::string>& moduleName) const
|
||||
+{
|
||||
+ sr_data_t* data;
|
||||
+ auto res = sr_get_oper_changes(m_sess.get(), moduleName ? moduleName->c_str() : nullptr, &data);
|
||||
+
|
||||
+ throwIfError(res, "Session::operationalChanges: Couldn't retrieve data'"s + (moduleName ? " for \"" + *moduleName + '"' : ""s), m_sess.get());
|
||||
+
|
||||
+ if (!data) {
|
||||
+ return std::nullopt;
|
||||
+ }
|
||||
+
|
||||
+ return wrapSrData(m_sess, data);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+/** @short Discard push operational changes of a module for this session
|
||||
+ *
|
||||
+ * Wraps `sr_discard_oper_changes`.
|
||||
+ *
|
||||
+ * */
|
||||
+void Session::discardOperationalChanges(const std::optional<std::string>& moduleName, std::chrono::milliseconds timeout)
|
||||
+{
|
||||
+ auto res = sr_discard_oper_changes(nullptr, m_sess.get(), moduleName ? nullptr : moduleName->c_str(), timeout.count());
|
||||
+ throwIfError(res, "Session::discardOoperationalChanges: Couldn't discard "s + (moduleName ? "for module \"" + *moduleName + "\"" : "globally"s), m_sess.get());
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Moves item (a list or a leaf-list) specified by `path`.
|
||||
* @param path Node to move.
|
||||
@@ -155,25 +216,6 @@
|
||||
throwIfError(res, "Session::moveItem: Can't move '"s + path + "'", m_sess.get());
|
||||
}
|
||||
|
||||
-namespace {
|
||||
-libyang::DataNode wrapSrData(std::shared_ptr<sr_session_ctx_s> sess, sr_data_t* data)
|
||||
-{
|
||||
- // Since the lyd_node came from sysrepo and it is wrapped in a sr_data_t, we have to postpone calling the
|
||||
- // sr_release_data() until after we're "done" with the libyang::DataNode.
|
||||
- //
|
||||
- // Normally, sr_release_data() would free the lyd_data as well. However, it is possible that the user wants to
|
||||
- // manipulate the data tree (think unlink()) in a way which might have needed to overwrite the tree->data pointer.
|
||||
- // Just delegate all the freeing to the C++ wrapper around lyd_data. The sysrepo library doesn't care about this.
|
||||
- auto tree = std::exchange(data->tree, nullptr);
|
||||
-
|
||||
- // Use wrapRawNode, not wrapUnmanagedRawNode because we want to let the C++ wrapper manage memory.
|
||||
- // Note: We're capturing the session inside the lambda.
|
||||
- return libyang::wrapRawNode(tree, std::shared_ptr<sr_data_t>(data, [extend_session_lifetime = sess] (sr_data_t* data) {
|
||||
- sr_release_data(data);
|
||||
- }));
|
||||
-}
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* @brief Returns a tree which contains all nodes that match the provided XPath.
|
||||
*
|
||||
@@ -263,13 +305,15 @@
|
||||
}
|
||||
|
||||
/**
|
||||
- * Discards changes made in this Session.
|
||||
+ * Discards changes made earlier in this Session, optionally only below a given XPath
|
||||
*
|
||||
- * Wraps `sr_discard_changes`.
|
||||
+ * The changes are applied only after calling Session::applyChanges.
|
||||
+ *
|
||||
+ * Wraps `sr_discard_changes_xpath`.
|
||||
*/
|
||||
-void Session::discardChanges()
|
||||
+void Session::discardChanges(const std::optional<std::string>& xpath)
|
||||
{
|
||||
- auto res = sr_discard_changes(m_sess.get());
|
||||
+ auto res = sr_discard_changes_xpath(m_sess.get(), xpath ? xpath->c_str() : nullptr);
|
||||
|
||||
throwIfError(res, "Session::discardChanges: Couldn't discard changes", m_sess.get());
|
||||
}
|
||||
diff --git a/tests/session.cpp b/tests/session.cpp
|
||||
index f762f10..2637f67 100644
|
||||
--- a/tests/session.cpp
|
||||
+++ b/tests/session.cpp
|
||||
@@ -211,7 +211,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
- DOCTEST_SUBCASE("Session::deleteOperItem")
|
||||
+ DOCTEST_SUBCASE("push operational data and deleting stuff")
|
||||
{
|
||||
// Set some arbitrary leaf.
|
||||
sess.setItem(leaf, "123");
|
||||
@@ -230,15 +230,51 @@
|
||||
sess.switchDatastore(sysrepo::Datastore::Operational);
|
||||
REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
|
||||
- // After using deleteItem, the leaf is no longer accesible from the operational datastore.
|
||||
- sess.deleteItem(leaf);
|
||||
- sess.applyChanges();
|
||||
- REQUIRE(!sess.getData(leaf));
|
||||
+ DOCTEST_SUBCASE("discardOperationalChanges")
|
||||
+ {
|
||||
+ // apply a change which makes the leaf disappear
|
||||
+ sess.dropForeignOperationalContent(leaf);
|
||||
+ REQUIRE(!!sess.getData(leaf));
|
||||
+ sess.applyChanges();
|
||||
+ REQUIRE(!sess.getData(leaf));
|
||||
|
||||
- // Using discardItems makes the leaf visible again (in the operational datastore).
|
||||
- sess.discardItems(leaf);
|
||||
- sess.applyChanges();
|
||||
- REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
+ // Using discardOperationalChanges makes the leaf visible again (in the operational datastore).
|
||||
+ // Also, no need to applyChanges().
|
||||
+ sess.discardOperationalChanges("test_module");
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
+ }
|
||||
+
|
||||
+ DOCTEST_SUBCASE("direct edit of a libyang::DataNode")
|
||||
+ {
|
||||
+ // at first, set the leaf to some random value
|
||||
+ sess.setItem(leaf, "456");
|
||||
+ sess.applyChanges();
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "456");
|
||||
+
|
||||
+ // change the edit in-place
|
||||
+ auto pushed = sess.operationalChanges();
|
||||
+ REQUIRE(pushed->path() == leaf);
|
||||
+ pushed->asTerm().changeValue("666");
|
||||
+ sess.editBatch(*pushed, sysrepo::DefaultOperation::Replace);
|
||||
+ sess.applyChanges();
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "666");
|
||||
+
|
||||
+ // Remove that previous edit in-place. Since the new edit cannot be empty, set some other leaf.
|
||||
+ pushed = sess.operationalChanges();
|
||||
+ auto another = "/test_module:popelnice/s"s;
|
||||
+ pushed->newPath(another, "xxx");
|
||||
+ pushed = *pushed->findPath(another);
|
||||
+ pushed->findPath(leaf)->unlink();
|
||||
+ // "the edit" for sysrepo must refer to a top-level node
|
||||
+ while (pushed->parent()) {
|
||||
+ pushed = *pushed->parent();
|
||||
+ }
|
||||
+ REQUIRE(!pushed->findPath(leaf));
|
||||
+ REQUIRE(!!pushed->findPath(another));
|
||||
+ sess.editBatch(*pushed, sysrepo::DefaultOperation::Replace);
|
||||
+ sess.applyChanges();
|
||||
+ REQUIRE(sess.getData(leaf)->asTerm().valueStr() == "123");
|
||||
+ }
|
||||
}
|
||||
|
||||
DOCTEST_SUBCASE("edit batch")
|
||||
@@ -321,6 +357,11 @@
|
||||
sess.discardChanges();
|
||||
}
|
||||
|
||||
+ DOCTEST_SUBCASE("discard XPath")
|
||||
+ {
|
||||
+ sess.discardChanges(leaf);
|
||||
+ }
|
||||
+
|
||||
REQUIRE(sess.getPendingChanges() == std::nullopt);
|
||||
}
|
||||
|
||||
+7
-3
@@ -1,19 +1,23 @@
|
||||
From 063f9b1696a4570aa61f02eb443d6752cab11c0c Mon Sep 17 00:00:00 2001
|
||||
From 2950046cd17bf9296a0b70b8f6b38114f6985864 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Thu, 22 Jun 2023 10:24:57 +0200
|
||||
Subject: [PATCH 1/3] Allow 'factory' as copy-from (only) in rpc copy-config
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/netconf.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/netconf.c b/src/netconf.c
|
||||
index e0b790f..8ae4160 100644
|
||||
index f1cc6b3..fdd7297 100644
|
||||
--- a/src/netconf.c
|
||||
+++ b/src/netconf.c
|
||||
@@ -361,6 +361,8 @@ np2srv_rpc_copyconfig_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), con
|
||||
@@ -369,6 +369,8 @@ np2srv_rpc_copyconfig_cb(sr_session_ctx_t *session, uint32_t UNUSED(sub_id), con
|
||||
ds = SR_DS_STARTUP;
|
||||
} else if (!strcmp(nodeset->dnodes[0]->schema->name, "candidate")) {
|
||||
ds = SR_DS_CANDIDATE;
|
||||
+3
-3
@@ -1,4 +1,4 @@
|
||||
From 26e36c7db9ebf11bf057a53e0c16238bda14792c Mon Sep 17 00:00:00 2001
|
||||
From d2e4e60838761e2bdd02d651b8e0bea47cc2dcb5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Tue, 2 Jul 2024 14:56:15 +0200
|
||||
Subject: [PATCH 2/3] Disable local users (backwards compat with older model)
|
||||
@@ -32,10 +32,10 @@ index 25e531b..13234e1 100644
|
||||
"ietf-tls-server@2023-12-28.yang -e server-ident-x509-cert -e client-auth-supported -e client-auth-x509-cert"
|
||||
"ietf-netconf-server@2023-12-28.yang -e ssh-listen -e tls-listen -e ssh-call-home -e tls-call-home -e central-netconf-server-supported"
|
||||
diff --git a/scripts/merge_config.sh b/scripts/merge_config.sh
|
||||
index 4b476d6..e588369 100755
|
||||
index eddada7..61af617 100755
|
||||
--- a/scripts/merge_config.sh
|
||||
+++ b/scripts/merge_config.sh
|
||||
@@ -81,9 +81,6 @@ CONFIG="<netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\
|
||||
@@ -89,9 +89,6 @@ CONFIG="<netconf-server xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-server\
|
||||
</public-key>
|
||||
</host-key>
|
||||
</server-identity>
|
||||
@@ -0,0 +1,36 @@
|
||||
From 2137bc0d614ad0aeabc37fd0041d05bc341a9007 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Fri, 10 Jan 2025 08:55:38 +0100
|
||||
Subject: [PATCH 01/22] modinfo BUGFIX add NP containers to push oper data
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
... so that oper get subscriptions for the
|
||||
containers are called.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/modinfo.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/modinfo.c b/src/modinfo.c
|
||||
index a58717f8..14d0b2ae 100644
|
||||
--- a/src/modinfo.c
|
||||
+++ b/src/modinfo.c
|
||||
@@ -1459,6 +1459,11 @@ sr_module_oper_data_update(struct sr_mod_info_mod_s *mod, const char *orig_name,
|
||||
if ((err_info = sr_module_oper_data_load(mod, conn, 0, NULL, data))) {
|
||||
return err_info;
|
||||
}
|
||||
+
|
||||
+ /* add any missing NP containers in the data */
|
||||
+ if ((err_info = sr_lyd_new_implicit_module(data, mod->ly_mod, LYD_IMPLICIT_NO_DEFAULTS, NULL))) {
|
||||
+ return err_info;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (get_oper_opts & SR_OPER_NO_SUBS) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From d4cded05509b63083283ba3a9104b27663c7eb39 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Fri, 10 Jan 2025 08:56:29 +0100
|
||||
Subject: [PATCH 02/22] sysrepo BUGFIX wrong param
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/sysrepo.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 844e11a5..7c96243c 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -3578,7 +3578,7 @@ sr_delete_item(sr_session_ctx_t *session, const char *path, const sr_edit_option
|
||||
/* just delete the selected node */
|
||||
node = NULL;
|
||||
if (session->dt[session->ds].edit->tree &&
|
||||
- (err_info = sr_lyd_find_path(session->dt[session->ds].edit->tree, path, 1, &node))) {
|
||||
+ (err_info = sr_lyd_find_path(session->dt[session->ds].edit->tree, path, 0, &node))) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (node) {
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 526da167043615ab9a0a8d36d4dd4a92644a0f58 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Fri, 10 Jan 2025 08:56:54 +0100
|
||||
Subject: [PATCH 03/22] SOVERSION bump to version 7.29.11
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 84990130..4ecfe4d9 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -62,7 +62,7 @@ set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_
|
||||
# with backward compatible change and micro version is connected with any internal change of the library.
|
||||
set(SYSREPO_MAJOR_SOVERSION 7)
|
||||
set(SYSREPO_MINOR_SOVERSION 29)
|
||||
-set(SYSREPO_MICRO_SOVERSION 10)
|
||||
+set(SYSREPO_MICRO_SOVERSION 11)
|
||||
set(SYSREPO_SOVERSION_FULL ${SYSREPO_MAJOR_SOVERSION}.${SYSREPO_MINOR_SOVERSION}.${SYSREPO_MICRO_SOVERSION})
|
||||
set(SYSREPO_SOVERSION ${SYSREPO_MAJOR_SOVERSION})
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 880e15c69312a471c85a8f125e5c0ade3a93dcb1 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Fri, 10 Jan 2025 08:57:04 +0100
|
||||
Subject: [PATCH 04/22] VERSION bump to version 3.3.11
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 4ecfe4d9..9f3cfde0 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -54,7 +54,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
|
||||
set(SYSREPO_MAJOR_VERSION 3)
|
||||
set(SYSREPO_MINOR_VERSION 3)
|
||||
-set(SYSREPO_MICRO_VERSION 10)
|
||||
+set(SYSREPO_MICRO_VERSION 11)
|
||||
set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_MICRO_VERSION})
|
||||
|
||||
# Version of the library
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+963
@@ -0,0 +1,963 @@
|
||||
From 31af3459bd8ea24228e2b13193176af6c34c289e Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Mon, 13 Jan 2025 11:19:30 +0100
|
||||
Subject: [PATCH 05/22] sysrepo UPDATE generate notifications on module changes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
modules/sysrepo-notifications@2025-01-10.yang | 97 ++++++
|
||||
modules/sysrepo_notifications_yang.h | 208 ++++++++++++
|
||||
src/common.c | 295 +++++++++++++++++-
|
||||
src/common.h | 42 ++-
|
||||
src/lyd_mods.c | 4 +
|
||||
src/modinfo.c | 2 +-
|
||||
src/replay.c | 42 +--
|
||||
src/replay.h | 10 +-
|
||||
src/sysrepo.c | 20 +-
|
||||
tests/test_oper_pull.c | 6 +
|
||||
10 files changed, 693 insertions(+), 33 deletions(-)
|
||||
create mode 100644 modules/sysrepo-notifications@2025-01-10.yang
|
||||
create mode 100644 modules/sysrepo_notifications_yang.h
|
||||
|
||||
diff --git a/modules/sysrepo-notifications@2025-01-10.yang b/modules/sysrepo-notifications@2025-01-10.yang
|
||||
new file mode 100644
|
||||
index 00000000..73df4353
|
||||
--- /dev/null
|
||||
+++ b/modules/sysrepo-notifications@2025-01-10.yang
|
||||
@@ -0,0 +1,97 @@
|
||||
+module sysrepo-notifications {
|
||||
+ namespace "http://www.sysrepo.org/yang/sysrepo-notifications";
|
||||
+ prefix srn;
|
||||
+
|
||||
+ yang-version 1.1;
|
||||
+
|
||||
+ import ietf-yang-library {
|
||||
+ prefix yanglib;
|
||||
+ }
|
||||
+
|
||||
+ organization
|
||||
+ "CESNET";
|
||||
+
|
||||
+ contact
|
||||
+ "Author: Michal Vasko
|
||||
+ <mvasko@cesnet.cz>";
|
||||
+
|
||||
+ description
|
||||
+ "Sysrepo YANG notifications for various events.";
|
||||
+
|
||||
+ revision "2025-01-10" {
|
||||
+ description
|
||||
+ "Initial revision.";
|
||||
+ }
|
||||
+
|
||||
+ typedef module-revision {
|
||||
+ type union {
|
||||
+ type yanglib:revision-identifier;
|
||||
+ type string {
|
||||
+ length "0";
|
||||
+ }
|
||||
+ }
|
||||
+ description
|
||||
+ "The YANG module revision date.
|
||||
+ A zero-length string is used if no revision statement
|
||||
+ is present in the YANG module.";
|
||||
+ }
|
||||
+
|
||||
+ notification module-change {
|
||||
+ description
|
||||
+ "YANG module change occurred.";
|
||||
+
|
||||
+ leaf name {
|
||||
+ type string;
|
||||
+ mandatory true;
|
||||
+ description
|
||||
+ "Name of the changed module.";
|
||||
+ }
|
||||
+
|
||||
+ leaf revision {
|
||||
+ type module-revision;
|
||||
+ mandatory true;
|
||||
+ description
|
||||
+ "Revision of the module.";
|
||||
+ }
|
||||
+
|
||||
+ leaf change {
|
||||
+ type enumeration {
|
||||
+ enum installed {
|
||||
+ description
|
||||
+ "New module was installed.";
|
||||
+ }
|
||||
+ enum uninstalled {
|
||||
+ description
|
||||
+ "Module was uninstalled.";
|
||||
+ }
|
||||
+ enum updated {
|
||||
+ description
|
||||
+ "Module was updated to a newer revision.";
|
||||
+ }
|
||||
+ enum feature-enabled {
|
||||
+ description
|
||||
+ "Feature was enabled in a module.";
|
||||
+ }
|
||||
+ enum feature-disabled {
|
||||
+ description
|
||||
+ "Feature was disabled in a module.";
|
||||
+ }
|
||||
+ }
|
||||
+ mandatory true;
|
||||
+ description
|
||||
+ "Type of the module change.";
|
||||
+ }
|
||||
+
|
||||
+ leaf old-revision {
|
||||
+ when "../change = 'updated'";
|
||||
+ type module-revision;
|
||||
+ mandatory true;
|
||||
+ }
|
||||
+
|
||||
+ leaf feature-name {
|
||||
+ when "../change = ('feature-enabled' or 'feature-disabled')";
|
||||
+ type string;
|
||||
+ mandatory true;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/modules/sysrepo_notifications_yang.h b/modules/sysrepo_notifications_yang.h
|
||||
new file mode 100644
|
||||
index 00000000..8f99c518
|
||||
--- /dev/null
|
||||
+++ b/modules/sysrepo_notifications_yang.h
|
||||
@@ -0,0 +1,208 @@
|
||||
+char sysrepo_notifications_yang[] = {
|
||||
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x79, 0x73, 0x72, 0x65,
|
||||
+ 0x70, 0x6f, 0x2d, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
|
||||
+ 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6e,
|
||||
+ 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x22, 0x68, 0x74,
|
||||
+ 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x73,
|
||||
+ 0x72, 0x65, 0x70, 0x6f, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x79, 0x61, 0x6e,
|
||||
+ 0x67, 0x2f, 0x73, 0x79, 0x73, 0x72, 0x65, 0x70, 0x6f, 0x2d, 0x6e, 0x6f,
|
||||
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22,
|
||||
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78,
|
||||
+ 0x20, 0x73, 0x72, 0x6e, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x79,
|
||||
+ 0x61, 0x6e, 0x67, 0x2d, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20,
|
||||
+ 0x31, 0x2e, 0x31, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6d,
|
||||
+ 0x70, 0x6f, 0x72, 0x74, 0x20, 0x69, 0x65, 0x74, 0x66, 0x2d, 0x79, 0x61,
|
||||
+ 0x6e, 0x67, 0x2d, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x79, 0x20, 0x7b,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x72, 0x65,
|
||||
+ 0x66, 0x69, 0x78, 0x20, 0x79, 0x61, 0x6e, 0x67, 0x6c, 0x69, 0x62, 0x3b,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x43, 0x45,
|
||||
+ 0x53, 0x4e, 0x45, 0x54, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x22, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x3a,
|
||||
+ 0x20, 0x4d, 0x69, 0x63, 0x68, 0x61, 0x6c, 0x20, 0x56, 0x61, 0x73, 0x6b,
|
||||
+ 0x6f, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x76, 0x61, 0x73,
|
||||
+ 0x6b, 0x6f, 0x40, 0x63, 0x65, 0x73, 0x6e, 0x65, 0x74, 0x2e, 0x63, 0x7a,
|
||||
+ 0x3e, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73,
|
||||
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x53, 0x79, 0x73, 0x72, 0x65, 0x70,
|
||||
+ 0x6f, 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66,
|
||||
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x66, 0x6f, 0x72,
|
||||
+ 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x65, 0x76, 0x65,
|
||||
+ 0x6e, 0x74, 0x73, 0x2e, 0x22, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x22, 0x32, 0x30,
|
||||
+ 0x32, 0x35, 0x2d, 0x30, 0x31, 0x2d, 0x31, 0x30, 0x22, 0x20, 0x7b, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63,
|
||||
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x49, 0x6e, 0x69,
|
||||
+ 0x74, 0x69, 0x61, 0x6c, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
+ 0x6e, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x64, 0x65, 0x66, 0x20,
|
||||
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2d, 0x72, 0x65, 0x76, 0x69, 0x73,
|
||||
+ 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x75, 0x6e, 0x69, 0x6f, 0x6e,
|
||||
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x79, 0x61, 0x6e, 0x67,
|
||||
+ 0x6c, 0x69, 0x62, 0x3a, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
|
||||
+ 0x2d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x3b,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
|
||||
+ 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x6e, 0x67, 0x74,
|
||||
+ 0x68, 0x20, 0x22, 0x30, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
|
||||
+ 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x22, 0x54, 0x68, 0x65, 0x20, 0x59, 0x41, 0x4e, 0x47,
|
||||
+ 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x72, 0x65, 0x76, 0x69,
|
||||
+ 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x0a, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x41, 0x20, 0x7a, 0x65, 0x72, 0x6f, 0x2d, 0x6c, 0x65, 0x6e, 0x67, 0x74,
|
||||
+ 0x68, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20,
|
||||
+ 0x75, 0x73, 0x65, 0x64, 0x20, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x20, 0x72,
|
||||
+ 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x73, 0x74, 0x61, 0x74,
|
||||
+ 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x73, 0x20, 0x70, 0x72,
|
||||
+ 0x65, 0x73, 0x65, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65,
|
||||
+ 0x20, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
|
||||
+ 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
|
||||
+ 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2d, 0x63,
|
||||
+ 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
|
||||
+ 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x22, 0x59, 0x41, 0x4e, 0x47, 0x20, 0x6d, 0x6f,
|
||||
+ 0x64, 0x75, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20,
|
||||
+ 0x6f, 0x63, 0x63, 0x75, 0x72, 0x72, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61,
|
||||
+ 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
|
||||
+ 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61,
|
||||
+ 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x72, 0x75, 0x65,
|
||||
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
+ 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x4e, 0x61, 0x6d, 0x65, 0x20,
|
||||
+ 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
+ 0x65, 0x64, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x22, 0x3b,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61, 0x66,
|
||||
+ 0x20, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x74, 0x79, 0x70, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2d,
|
||||
+ 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61,
|
||||
+ 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x72, 0x75, 0x65,
|
||||
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
|
||||
+ 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x52, 0x65, 0x76, 0x69, 0x73,
|
||||
+ 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6d,
|
||||
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x6c, 0x65, 0x61, 0x66, 0x20, 0x63, 0x68, 0x61,
|
||||
+ 0x6e, 0x67, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x65,
|
||||
+ 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x69, 0x6e,
|
||||
+ 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
|
||||
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x4e, 0x65, 0x77, 0x20, 0x6d,
|
||||
+ 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x69, 0x6e,
|
||||
+ 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x2e, 0x22, 0x3b, 0x0a, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75,
|
||||
+ 0x6d, 0x20, 0x75, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65,
|
||||
+ 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x22, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20,
|
||||
+ 0x75, 0x6e, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x65, 0x64, 0x2e,
|
||||
+ 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
|
||||
+ 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x22, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20,
|
||||
+ 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x61,
|
||||
+ 0x20, 0x6e, 0x65, 0x77, 0x65, 0x72, 0x20, 0x72, 0x65, 0x76, 0x69, 0x73,
|
||||
+ 0x69, 0x6f, 0x6e, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e, 0x75, 0x6d, 0x20, 0x66, 0x65,
|
||||
+ 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65,
|
||||
+ 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x22, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x77, 0x61, 0x73,
|
||||
+ 0x20, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20,
|
||||
+ 0x61, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x22, 0x3b, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6e,
|
||||
+ 0x75, 0x6d, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x64,
|
||||
+ 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
|
||||
+ 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x46, 0x65, 0x61, 0x74, 0x75,
|
||||
+ 0x72, 0x65, 0x20, 0x77, 0x61, 0x73, 0x20, 0x64, 0x69, 0x73, 0x61, 0x62,
|
||||
+ 0x6c, 0x65, 0x64, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x20, 0x6d, 0x6f, 0x64,
|
||||
+ 0x75, 0x6c, 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
|
||||
+ 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79,
|
||||
+ 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x65, 0x73, 0x63, 0x72,
|
||||
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
|
||||
+ 0x54, 0x79, 0x70, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
|
||||
+ 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x63, 0x68, 0x61, 0x6e, 0x67,
|
||||
+ 0x65, 0x2e, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x6c, 0x65, 0x61, 0x66, 0x20, 0x6f, 0x6c, 0x64, 0x2d, 0x72, 0x65, 0x76,
|
||||
+ 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x65, 0x6e,
|
||||
+ 0x20, 0x22, 0x2e, 0x2e, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20,
|
||||
+ 0x3d, 0x20, 0x27, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x27, 0x22,
|
||||
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x6d, 0x6f, 0x64, 0x75, 0x6c,
|
||||
+ 0x65, 0x2d, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x3b, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x6d, 0x61, 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x72,
|
||||
+ 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
|
||||
+ 0x65, 0x61, 0x66, 0x20, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d,
|
||||
+ 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x65, 0x6e, 0x20,
|
||||
+ 0x22, 0x2e, 0x2e, 0x2f, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x3d,
|
||||
+ 0x20, 0x28, 0x27, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x65,
|
||||
+ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27,
|
||||
+ 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x2d, 0x64, 0x69, 0x73, 0x61,
|
||||
+ 0x62, 0x6c, 0x65, 0x64, 0x27, 0x29, 0x22, 0x3b, 0x0a, 0x20, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x79, 0x70,
|
||||
+ 0x65, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3b, 0x0a, 0x20, 0x20,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61,
|
||||
+ 0x6e, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x79, 0x20, 0x74, 0x72, 0x75, 0x65,
|
||||
+ 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
|
||||
+ 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x00
|
||||
+};
|
||||
diff --git a/src/common.c b/src/common.c
|
||||
index 10a379c0..72f3fc93 100644
|
||||
--- a/src/common.c
|
||||
+++ b/src/common.c
|
||||
@@ -55,10 +55,12 @@
|
||||
#include "modinfo.h"
|
||||
#include "plugins_datastore.h"
|
||||
#include "plugins_notification.h"
|
||||
+#include "replay.h"
|
||||
#include "shm_ext.h"
|
||||
#include "shm_main.h"
|
||||
#include "shm_mod.h"
|
||||
#include "shm_sub.h"
|
||||
+#include "subscr.h"
|
||||
#include "sysrepo.h"
|
||||
|
||||
#define SR_IS_YANG_ID_CHAR(c) (isalpha(c) || isdigit(c) || ((c) == '_') || ((c) == '-') || ((c) == '.'))
|
||||
@@ -965,9 +967,9 @@ sr_module_default_mode(const struct lys_module *ly_mod)
|
||||
if (!strcmp(ly_mod->name, "sysrepo")) {
|
||||
return SR_INTMOD_MAIN_FILE_PERM;
|
||||
} else if (sr_is_module_internal(ly_mod)) {
|
||||
- if (!strcmp(ly_mod->name, "sysrepo-plugind") || !strcmp(ly_mod->name, "ietf-yang-schema-mount") ||
|
||||
- !strcmp(ly_mod->name, "ietf-yang-library") || !strcmp(ly_mod->name, "ietf-netconf-notifications") ||
|
||||
- !strcmp(ly_mod->name, "ietf-netconf")) {
|
||||
+ if (!strcmp(ly_mod->name, "sysrepo-plugind") || !strcmp(ly_mod->name, "sysrepo-notifications") ||
|
||||
+ !strcmp(ly_mod->name, "ietf-yang-schema-mount") || !strcmp(ly_mod->name, "ietf-yang-library") ||
|
||||
+ !strcmp(ly_mod->name, "ietf-netconf-notifications") || !strcmp(ly_mod->name, "ietf-netconf")) {
|
||||
return SR_INTMOD_WITHDATA_FILE_PERM;
|
||||
} else if (!strcmp(ly_mod->name, "ietf-netconf-acm") || !strcmp(ly_mod->name, "sysrepo-monitoring")) {
|
||||
return SR_INTMOD_NACM_SRMON_FILE_PERM;
|
||||
@@ -5551,3 +5553,290 @@ sr_is_prod_env(void)
|
||||
}
|
||||
return sr_prod_env;
|
||||
}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Check whether a 'sysrepo-notifications' notification even need to be generated.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] shm_mod SHM mod.
|
||||
+ * @param[out] subs_or_replay Set if there are any subscribers or replay is enabled for the module.
|
||||
+ * @return err_info, NULL on success.
|
||||
+ */
|
||||
+static sr_error_info_t *
|
||||
+sr_generate_notif_has_subs_or_replay(sr_conn_ctx_t *conn, sr_mod_t *shm_mod, int *subs_or_replay)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ sr_mod_notif_sub_t *notif_subs;
|
||||
+ uint32_t notif_sub_count;
|
||||
+
|
||||
+ /* EXT READ LOCK */
|
||||
+ if ((err_info = sr_shmext_conn_remap_lock(conn, SR_LOCK_READ, 0, __func__))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* get subscriber count */
|
||||
+ err_info = sr_notif_find_subscriber(conn, "sysrepo-notifications", ¬if_subs, ¬if_sub_count, NULL);
|
||||
+
|
||||
+ /* EXT READ UNLOCK */
|
||||
+ sr_shmext_conn_remap_unlock(conn, SR_LOCK_READ, 0, __func__);
|
||||
+
|
||||
+ if (err_info) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* check replay support and subscribers */
|
||||
+ if (!shm_mod->replay_supp && !notif_sub_count) {
|
||||
+ /* no subscribers and replay off */
|
||||
+ *subs_or_replay = 0;
|
||||
+ } else {
|
||||
+ *subs_or_replay = 1;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ return err_info;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * @brief Send a generated notification.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] shm_mod SHM mod.
|
||||
+ * @param[in] notif Notification to send.
|
||||
+ * @return err_info, NULL on success.
|
||||
+ */
|
||||
+static sr_error_info_t *
|
||||
+sr_generate_notif_send(sr_conn_ctx_t *conn, sr_mod_t *shm_mod, const struct lyd_node *notif)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ struct timespec notif_ts_mono, notif_ts_real;
|
||||
+
|
||||
+ /* NOTIF SUB READ LOCK */
|
||||
+ if ((err_info = sr_rwlock(&shm_mod->notif_lock, SR_SHMEXT_SUB_LOCK_TIMEOUT, SR_LOCK_READ, conn->cid,
|
||||
+ __func__, NULL, NULL))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* remember when the notification was generated */
|
||||
+ sr_timeouttime_get(¬if_ts_mono, 0);
|
||||
+ sr_realtime_get(¬if_ts_real);
|
||||
+
|
||||
+ /* send the notification (non-validated, must be valid) */
|
||||
+ err_info = sr_shmsub_notif_notify(conn, notif, notif_ts_mono, notif_ts_real, NULL, NULL, 0, 0);
|
||||
+
|
||||
+ /* NOTIF SUB READ UNLOCK */
|
||||
+ sr_rwunlock(&shm_mod->notif_lock, SR_SHMEXT_SUB_LOCK_TIMEOUT, SR_LOCK_READ, conn->cid, __func__);
|
||||
+
|
||||
+ if (err_info) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* store the notification for a replay */
|
||||
+ if ((err_info = sr_replay_store(conn, NULL, notif, notif_ts_real))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ return err_info;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sr_generate_notif_module_change_installed(sr_conn_ctx_t *conn, sr_int_install_mod_t *new_mods, uint32_t new_mod_count)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ struct lyd_node *notif = NULL;
|
||||
+ sr_mod_t *shm_mod;
|
||||
+ uint32_t i;
|
||||
+ int subs_or_replay;
|
||||
+
|
||||
+ /* get this module */
|
||||
+ shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(conn), "sysrepo-notifications");
|
||||
+ SR_CHECK_INT_GOTO(!shm_mod, err_info, cleanup);
|
||||
+
|
||||
+ /* check whether to even generate any notifications */
|
||||
+ if ((err_info = sr_generate_notif_has_subs_or_replay(conn, shm_mod, &subs_or_replay)) || !subs_or_replay) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < new_mod_count; ++i) {
|
||||
+ /* generate the notifcation */
|
||||
+ if ((err_info = sr_lyd_new_path(NULL, conn->ly_ctx, "/sysrepo-notifications:module-change", NULL, 0, NULL,
|
||||
+ ¬if))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "name", new_mods[i].ly_mod->name))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "revision", new_mods[i].ly_mod->revision))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "change", "installed"))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* send it */
|
||||
+ if ((err_info = sr_generate_notif_send(conn, shm_mod, notif))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ lyd_free_siblings(notif);
|
||||
+ notif = NULL;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ lyd_free_siblings(notif);
|
||||
+ sr_errinfo_free(&err_info);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sr_generate_notif_module_change_uninstalled(sr_conn_ctx_t *conn, struct ly_set *mod_set)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ struct lyd_node *notif = NULL;
|
||||
+ const struct lys_module *ly_mod;
|
||||
+ sr_mod_t *shm_mod;
|
||||
+ uint32_t i;
|
||||
+ int subs_or_replay;
|
||||
+
|
||||
+ /* get this module */
|
||||
+ shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(conn), "sysrepo-notifications");
|
||||
+ SR_CHECK_INT_GOTO(!shm_mod, err_info, cleanup);
|
||||
+
|
||||
+ /* check whether to even generate any notifications */
|
||||
+ if ((err_info = sr_generate_notif_has_subs_or_replay(conn, shm_mod, &subs_or_replay)) || !subs_or_replay) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < mod_set->count; ++i) {
|
||||
+ ly_mod = mod_set->objs[i];
|
||||
+
|
||||
+ /* generate the notifcation */
|
||||
+ if ((err_info = sr_lyd_new_path(NULL, conn->ly_ctx, "/sysrepo-notifications:module-change", NULL, 0, NULL,
|
||||
+ ¬if))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "name", ly_mod->name))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "revision", ly_mod->revision))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "change", "uninstalled"))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* send it */
|
||||
+ if ((err_info = sr_generate_notif_send(conn, shm_mod, notif))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ lyd_free_siblings(notif);
|
||||
+ notif = NULL;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ lyd_free_siblings(notif);
|
||||
+ sr_errinfo_free(&err_info);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sr_generate_notif_module_change_updated(sr_conn_ctx_t *conn, struct ly_set *old_mod_set, struct ly_set *upd_mod_set)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ struct lyd_node *notif = NULL;
|
||||
+ const struct lys_module *ly_mod;
|
||||
+ sr_mod_t *shm_mod;
|
||||
+ uint32_t i;
|
||||
+ int subs_or_replay;
|
||||
+
|
||||
+ /* get this module */
|
||||
+ shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(conn), "sysrepo-notifications");
|
||||
+ SR_CHECK_INT_GOTO(!shm_mod, err_info, cleanup);
|
||||
+
|
||||
+ /* check whether to even generate any notifications */
|
||||
+ if ((err_info = sr_generate_notif_has_subs_or_replay(conn, shm_mod, &subs_or_replay)) || !subs_or_replay) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < upd_mod_set->count; ++i) {
|
||||
+ ly_mod = upd_mod_set->objs[i];
|
||||
+
|
||||
+ /* generate the notifcation */
|
||||
+ if ((err_info = sr_lyd_new_path(NULL, conn->ly_ctx, "/sysrepo-notifications:module-change", NULL, 0, NULL,
|
||||
+ ¬if))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "name", ly_mod->name))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "revision", ly_mod->revision))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "change", "updated"))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ ly_mod = old_mod_set->objs[i];
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "old-revision", ly_mod->revision))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* send it */
|
||||
+ if ((err_info = sr_generate_notif_send(conn, shm_mod, notif))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ lyd_free_siblings(notif);
|
||||
+ notif = NULL;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ lyd_free_siblings(notif);
|
||||
+ sr_errinfo_free(&err_info);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+sr_generate_notif_module_change_feature(sr_conn_ctx_t *conn, const struct lys_module *ly_mod, const char *feature_name,
|
||||
+ int enabled)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ struct lyd_node *notif = NULL;
|
||||
+ sr_mod_t *shm_mod;
|
||||
+ int subs_or_replay;
|
||||
+
|
||||
+ /* get this module */
|
||||
+ shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(conn), "sysrepo-notifications");
|
||||
+ SR_CHECK_INT_GOTO(!shm_mod, err_info, cleanup);
|
||||
+
|
||||
+ /* check whether to even generate any notifications */
|
||||
+ if ((err_info = sr_generate_notif_has_subs_or_replay(conn, shm_mod, &subs_or_replay)) || !subs_or_replay) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* generate the notifcation */
|
||||
+ if ((err_info = sr_lyd_new_path(NULL, conn->ly_ctx, "/sysrepo-notifications:module-change", NULL, 0, NULL,
|
||||
+ ¬if))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "name", ly_mod->name))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "revision", ly_mod->revision))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "change", enabled ? "feature-enabled" : "feature-disabled"))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if ((err_info = sr_lyd_new_term(notif, NULL, "feature-name", feature_name))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ /* send it */
|
||||
+ if ((err_info = sr_generate_notif_send(conn, shm_mod, notif))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+cleanup:
|
||||
+ lyd_free_siblings(notif);
|
||||
+ sr_errinfo_free(&err_info);
|
||||
+}
|
||||
diff --git a/src/common.h b/src/common.h
|
||||
index 99304bd7..9fc675d4 100644
|
||||
--- a/src/common.h
|
||||
+++ b/src/common.h
|
||||
@@ -4,8 +4,8 @@
|
||||
* @brief common routines header
|
||||
*
|
||||
* @copyright
|
||||
- * Copyright (c) 2018 - 2023 Deutsche Telekom AG.
|
||||
- * Copyright (c) 2018 - 2023 CESNET, z.s.p.o.
|
||||
+ * Copyright (c) 2018 - 2025 Deutsche Telekom AG.
|
||||
+ * Copyright (c) 2018 - 2025 CESNET, z.s.p.o.
|
||||
*
|
||||
* This source code is licensed under BSD 3-Clause License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
@@ -1371,4 +1371,42 @@ sr_error_info_t *sr_conn_info(sr_cid_t **cids, pid_t **pids, uint32_t *count, sr
|
||||
*/
|
||||
int sr_is_prod_env(void);
|
||||
|
||||
+/**
|
||||
+ * @brief Generate the 'module-change' notification for newly installed modules.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] new_mods Array of new modules.
|
||||
+ * @param[in] new_mod_count Count of @p new_mods.
|
||||
+ */
|
||||
+void sr_generate_notif_module_change_installed(sr_conn_ctx_t *conn, sr_int_install_mod_t *new_mods,
|
||||
+ uint32_t new_mod_count);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Generate the 'module-change' notification for uninstalled modules.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] mod_set Set of uninstalled modules.
|
||||
+ */
|
||||
+void sr_generate_notif_module_change_uninstalled(sr_conn_ctx_t *conn, struct ly_set *mod_set);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Generate the 'module-change' notification for updated modules.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] old_mod_set Set of old modules.
|
||||
+ * @param[in] upd_mod_set Set of updated modules.
|
||||
+ */
|
||||
+void sr_generate_notif_module_change_updated(sr_conn_ctx_t *conn, struct ly_set *old_mod_set, struct ly_set *upd_mod_set);
|
||||
+
|
||||
+/**
|
||||
+ * @brief Generate the 'module-change' notification for a module feature change.
|
||||
+ *
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] ly_mod Changed module.
|
||||
+ * @param[in] feature_name Changed feature name.
|
||||
+ * @param[in] enabled Whether the feature was enabled or disabled.
|
||||
+ */
|
||||
+void sr_generate_notif_module_change_feature(sr_conn_ctx_t *conn, const struct lys_module *ly_mod,
|
||||
+ const char *feature_name, int enabled);
|
||||
+
|
||||
#endif /* _COMMON_H */
|
||||
diff --git a/src/lyd_mods.c b/src/lyd_mods.c
|
||||
index 256f292e..77f8cd7b 100644
|
||||
--- a/src/lyd_mods.c
|
||||
+++ b/src/lyd_mods.c
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "../modules/ietf_netconf_yang.h"
|
||||
#include "../modules/ietf_origin_yang.h"
|
||||
#include "../modules/sysrepo_monitoring_yang.h"
|
||||
+#include "../modules/sysrepo_notifications_yang.h"
|
||||
#include "../modules/sysrepo_plugind_yang.h"
|
||||
|
||||
/**
|
||||
@@ -1000,6 +1001,9 @@ sr_lydmods_create(sr_conn_ctx_t *conn, struct ly_ctx *ly_ctx, struct lyd_node **
|
||||
/* install sysrepo-plugind */
|
||||
SR_INSTALL_INT_MOD(ly_ctx, sysrepo_plugind_yang, 0, new_mods, new_mod_count);
|
||||
|
||||
+ /* install sysrepo-notifications */
|
||||
+ SR_INSTALL_INT_MOD(ly_ctx, sysrepo_notifications_yang, 0, new_mods, new_mod_count);
|
||||
+
|
||||
/* install ietf-netconf (implemented dependency) and ietf-netconf-with-defaults */
|
||||
SR_INSTALL_INT_MOD(ly_ctx, ietf_netconf_yang, 1, new_mods, new_mod_count);
|
||||
SR_INSTALL_INT_MOD(ly_ctx, ietf_netconf_with_defaults_yang, 0, new_mods, new_mod_count);
|
||||
diff --git a/src/modinfo.c b/src/modinfo.c
|
||||
index 14d0b2ae..7414121e 100644
|
||||
--- a/src/modinfo.c
|
||||
+++ b/src/modinfo.c
|
||||
@@ -3824,7 +3824,7 @@ sr_modinfo_generate_config_change_notif(struct sr_mod_info_s *mod_info, sr_sessi
|
||||
}
|
||||
|
||||
/* store the notification for a replay */
|
||||
- if ((err_info = sr_replay_store(session, notif, notif_ts_real))) {
|
||||
+ if ((err_info = sr_replay_store(mod_info->conn, session, notif, notif_ts_real))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
diff --git a/src/replay.c b/src/replay.c
|
||||
index c31043de..00e63eec 100644
|
||||
--- a/src/replay.c
|
||||
+++ b/src/replay.c
|
||||
@@ -127,7 +127,7 @@ cleanup:
|
||||
}
|
||||
|
||||
sr_error_info_t *
|
||||
-sr_replay_store(sr_session_ctx_t *sess, const struct lyd_node *notif, struct timespec notif_ts)
|
||||
+sr_replay_store(sr_conn_ctx_t *conn, sr_session_ctx_t *sess, const struct lyd_node *notif, struct timespec notif_ts)
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
sr_mod_t *shm_mod;
|
||||
@@ -146,7 +146,7 @@ sr_replay_store(sr_session_ctx_t *sess, const struct lyd_node *notif, struct tim
|
||||
SR_CHECK_INT_RET(notif_op->schema->nodetype != LYS_NOTIF, err_info);
|
||||
|
||||
/* find SHM mod for replay lock and check if replay is even supported */
|
||||
- shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(sess->conn), ly_mod->name);
|
||||
+ shm_mod = sr_shmmod_find_module(SR_CONN_MOD_SHM(conn), ly_mod->name);
|
||||
SR_CHECK_INT_RET(!shm_mod, err_info);
|
||||
|
||||
if (!shm_mod->replay_supp) {
|
||||
@@ -154,32 +154,34 @@ sr_replay_store(sr_session_ctx_t *sess, const struct lyd_node *notif, struct tim
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- /* MUTEX LOCK */
|
||||
- sr_timeouttime_get(&timeout_ts, SR_NOTIF_BUF_LOCK_TIMEOUT);
|
||||
- if ((r = pthread_mutex_clocklock(&sess->notif_buf.lock.mutex, COMPAT_CLOCK_ID, &timeout_ts))) {
|
||||
- SR_ERRINFO_LOCK(&err_info, __func__, r);
|
||||
- return err_info;
|
||||
- }
|
||||
+ if (sess) {
|
||||
+ /* MUTEX LOCK */
|
||||
+ sr_timeouttime_get(&timeout_ts, SR_NOTIF_BUF_LOCK_TIMEOUT);
|
||||
+ if ((r = pthread_mutex_clocklock(&sess->notif_buf.lock.mutex, COMPAT_CLOCK_ID, &timeout_ts))) {
|
||||
+ SR_ERRINFO_LOCK(&err_info, __func__, r);
|
||||
+ return err_info;
|
||||
+ }
|
||||
|
||||
- if (sess->notif_buf.thread_running) {
|
||||
- /* store the notification in the buffer */
|
||||
- has_buf = 1;
|
||||
- err_info = sr_notif_buf_store(sess, notif, notif_ts);
|
||||
+ if (sess->notif_buf.thread_running) {
|
||||
+ /* store the notification in the buffer */
|
||||
+ has_buf = 1;
|
||||
+ err_info = sr_notif_buf_store(sess, notif, notif_ts);
|
||||
|
||||
- /* broadcast condition */
|
||||
- sr_cond_broadcast(&sess->notif_buf.lock.cond);
|
||||
- }
|
||||
+ /* broadcast condition */
|
||||
+ sr_cond_broadcast(&sess->notif_buf.lock.cond);
|
||||
+ }
|
||||
|
||||
- /* MUTEX UNLOCK */
|
||||
- pthread_mutex_unlock(&sess->notif_buf.lock.mutex);
|
||||
+ /* MUTEX UNLOCK */
|
||||
+ pthread_mutex_unlock(&sess->notif_buf.lock.mutex);
|
||||
|
||||
- if (err_info) {
|
||||
- return err_info;
|
||||
+ if (err_info) {
|
||||
+ return err_info;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (!has_buf) {
|
||||
/* write the notification to a replay file */
|
||||
- if ((err_info = sr_notif_write(sess->conn, shm_mod, notif, notif_ts))) {
|
||||
+ if ((err_info = sr_notif_write(conn, shm_mod, notif, notif_ts))) {
|
||||
return err_info;
|
||||
}
|
||||
}
|
||||
diff --git a/src/replay.h b/src/replay.h
|
||||
index ecf0cf25..7f3a851a 100644
|
||||
--- a/src/replay.h
|
||||
+++ b/src/replay.h
|
||||
@@ -4,8 +4,8 @@
|
||||
* @brief header for notification replay routines
|
||||
*
|
||||
* @copyright
|
||||
- * Copyright (c) 2018 - 2021 Deutsche Telekom AG.
|
||||
- * Copyright (c) 2018 - 2021 CESNET, z.s.p.o.
|
||||
+ * Copyright (c) 2018 - 2025 Deutsche Telekom AG.
|
||||
+ * Copyright (c) 2018 - 2025 CESNET, z.s.p.o.
|
||||
*
|
||||
* This source code is licensed under BSD 3-Clause License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
@@ -26,12 +26,14 @@
|
||||
/**
|
||||
* @brief Store a notification for replay.
|
||||
*
|
||||
- * @param[in] sess Session to use.
|
||||
+ * @param[in] conn Connection to use.
|
||||
+ * @param[in] sess Session to use, if available.
|
||||
* @param[in] notif Notification to store.
|
||||
* @param[in] notif_ts Notification timestamp to store.
|
||||
* @return err_info, NULL on success.
|
||||
*/
|
||||
-sr_error_info_t *sr_replay_store(sr_session_ctx_t *sess, const struct lyd_node *notif, struct timespec notif_ts);
|
||||
+sr_error_info_t *sr_replay_store(sr_conn_ctx_t *conn, sr_session_ctx_t *sess, const struct lyd_node *notif,
|
||||
+ struct timespec notif_ts);
|
||||
|
||||
/**
|
||||
* @brief Notification buffer thread.
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 7c96243c..614b5454 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -4,8 +4,8 @@
|
||||
* @brief sysrepo API routines
|
||||
*
|
||||
* @copyright
|
||||
- * Copyright (c) 2018 - 2024 Deutsche Telekom AG.
|
||||
- * Copyright (c) 2018 - 2024 CESNET, z.s.p.o.
|
||||
+ * Copyright (c) 2018 - 2025 Deutsche Telekom AG.
|
||||
+ * Copyright (c) 2018 - 2025 CESNET, z.s.p.o.
|
||||
*
|
||||
* This source code is licensed under BSD 3-Clause License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
@@ -1541,6 +1541,9 @@ _sr_install_modules(sr_conn_ctx_t *conn, const char *search_dirs, const char *da
|
||||
SR_CONN_MAIN_SHM(conn)->content_id = ly_ctx_get_modules_hash(new_ctx);
|
||||
sr_conn_ctx_switch(conn, &new_ctx, &old_ctx);
|
||||
|
||||
+ /* send the notification */
|
||||
+ sr_generate_notif_module_change_installed(conn, *new_mods, *new_mod_count);
|
||||
+
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
@@ -1859,6 +1862,9 @@ sr_remove_modules(sr_conn_ctx_t *conn, const char **module_names, int force)
|
||||
SR_CONN_MAIN_SHM(conn)->content_id = ly_ctx_get_modules_hash(new_ctx);
|
||||
sr_conn_ctx_switch(conn, &new_ctx, &old_ctx);
|
||||
|
||||
+ /* send the notification */
|
||||
+ sr_generate_notif_module_change_uninstalled(conn, &mod_set);
|
||||
+
|
||||
cleanup:
|
||||
sr_lycc_update_data_clear(&data_info);
|
||||
lyd_free_siblings(sr_mods);
|
||||
@@ -2104,6 +2110,9 @@ sr_update_modules(sr_conn_ctx_t *conn, const char **schema_paths, const char *se
|
||||
SR_CONN_MAIN_SHM(conn)->content_id = ly_ctx_get_modules_hash(new_ctx);
|
||||
sr_conn_ctx_switch(conn, &new_ctx, &old_ctx);
|
||||
|
||||
+ /* send the notification */
|
||||
+ sr_generate_notif_module_change_updated(conn, &old_mod_set, &upd_mod_set);
|
||||
+
|
||||
cleanup:
|
||||
sr_lycc_update_data_clear(&data_info);
|
||||
lyd_free_siblings(sr_mods);
|
||||
@@ -2606,6 +2615,9 @@ sr_change_module_feature(sr_conn_ctx_t *conn, const char *module_name, const cha
|
||||
SR_CONN_MAIN_SHM(conn)->content_id = ly_ctx_get_modules_hash(new_ctx);
|
||||
sr_conn_ctx_switch(conn, &new_ctx, &old_ctx);
|
||||
|
||||
+ /* send the notification */
|
||||
+ sr_generate_notif_module_change_feature(conn, ly_mod, feature_name, enable);
|
||||
+
|
||||
cleanup:
|
||||
sr_lycc_update_data_clear(&data_info);
|
||||
lyd_free_siblings(sr_mods);
|
||||
@@ -2735,6 +2747,8 @@ sr_is_module_internal(const struct lys_module *ly_mod)
|
||||
return 1;
|
||||
} else if (!strcmp(ly_mod->name, "sysrepo-plugind")) {
|
||||
return 1;
|
||||
+ } else if (!strcmp(ly_mod->name, "sysrepo-notifications")) {
|
||||
+ return 1;
|
||||
} else if (!strcmp(ly_mod->name, "ietf-netconf-acm")) {
|
||||
return 1;
|
||||
}
|
||||
@@ -7407,7 +7421,7 @@ sr_notif_send_tree(sr_session_ctx_t *session, struct lyd_node *notif, uint32_t t
|
||||
}
|
||||
|
||||
/* store the notification for a replay */
|
||||
- if ((err_info = sr_replay_store(session, notif_top, notif_ts_real))) {
|
||||
+ if ((err_info = sr_replay_store(session->conn, session, notif_top, notif_ts_real))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
diff --git a/tests/test_oper_pull.c b/tests/test_oper_pull.c
|
||||
index c9654faa..91ba526e 100644
|
||||
--- a/tests/test_oper_pull.c
|
||||
+++ b/tests/test_oper_pull.c
|
||||
@@ -406,6 +406,9 @@ test_sr_mon(void **state)
|
||||
" </datastore>\n"
|
||||
" </module>\n"
|
||||
" <module>\n"
|
||||
+ " <name>sysrepo-notifications</name>\n"
|
||||
+ " </module>\n"
|
||||
+ " <module>\n"
|
||||
" <name>ietf-netconf</name>\n"
|
||||
" </module>\n"
|
||||
" <module>\n"
|
||||
@@ -669,6 +672,9 @@ test_sr_mon(void **state)
|
||||
" </ds-lock>\n"
|
||||
" </module>\n"
|
||||
" <module>\n"
|
||||
+ " <name>sysrepo-notifications</name>\n"
|
||||
+ " </module>\n"
|
||||
+ " <module>\n"
|
||||
" <name>ietf-netconf</name>\n"
|
||||
" </module>\n"
|
||||
" <module>\n"
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From 05ef34960277dca49e1dda26eb2f4ffd5f1ba354 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Mon, 13 Jan 2025 11:19:51 +0100
|
||||
Subject: [PATCH 06/22] SOVERSION bump to version 7.29.12
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 9f3cfde0..fcb49a24 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -62,7 +62,7 @@ set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_
|
||||
# with backward compatible change and micro version is connected with any internal change of the library.
|
||||
set(SYSREPO_MAJOR_SOVERSION 7)
|
||||
set(SYSREPO_MINOR_SOVERSION 29)
|
||||
-set(SYSREPO_MICRO_SOVERSION 11)
|
||||
+set(SYSREPO_MICRO_SOVERSION 12)
|
||||
set(SYSREPO_SOVERSION_FULL ${SYSREPO_MAJOR_SOVERSION}.${SYSREPO_MINOR_SOVERSION}.${SYSREPO_MICRO_SOVERSION})
|
||||
set(SYSREPO_SOVERSION ${SYSREPO_MAJOR_SOVERSION})
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From 74f5fa11043e579b6c007a2ff1f5f1d880637b92 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Mon, 13 Jan 2025 11:20:00 +0100
|
||||
Subject: [PATCH 07/22] VERSION bump to version 3.4.0
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index fcb49a24..7d49cedb 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -53,8 +53,8 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
# minor version changes with added functionality (new tool, functionality of the tool or library, ...) and
|
||||
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
|
||||
set(SYSREPO_MAJOR_VERSION 3)
|
||||
-set(SYSREPO_MINOR_VERSION 3)
|
||||
-set(SYSREPO_MICRO_VERSION 11)
|
||||
+set(SYSREPO_MINOR_VERSION 4)
|
||||
+set(SYSREPO_MICRO_VERSION 0)
|
||||
set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_MICRO_VERSION})
|
||||
|
||||
# Version of the library
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
From a0e02874aaf24a9e94c501ac95c5b9f55c316500 Mon Sep 17 00:00:00 2001
|
||||
From: IrfanMohammad <irfan.haslanded@gmail.com>
|
||||
Date: Mon, 13 Jan 2025 08:19:04 +0000
|
||||
Subject: [PATCH 08/22] shmext REFACTOR conn_remap_unlock remove last hole
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
The logic in sr_shmext_conn_remap_unlock can be cleaner.
|
||||
|
||||
A call to sr_file_get_size() can be avoided since we already know it
|
||||
as `conn->ext_shm.size`.
|
||||
|
||||
Also cleanup the somewhat complex cast + arithmetic in a if condition.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/shm_ext.c | 16 +++++++---------
|
||||
1 file changed, 7 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/shm_ext.c b/src/shm_ext.c
|
||||
index f4103837..78930469 100644
|
||||
--- a/src/shm_ext.c
|
||||
+++ b/src/shm_ext.c
|
||||
@@ -131,8 +131,8 @@ sr_shmext_conn_remap_unlock(sr_conn_ctx_t *conn, sr_lock_mode_t mode, int ext_lo
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
sr_ext_hole_t *iter, *last = NULL;
|
||||
- uint32_t last_size;
|
||||
- size_t shm_file_size = 0;
|
||||
+ uint32_t new_size;
|
||||
+ char *last_hole_end;
|
||||
|
||||
/* make ext SHM smaller if there is a memory hole at its end */
|
||||
if (((mode == SR_LOCK_WRITE) || (mode == SR_LOCK_WRITE_URGE)) && ext_lock) {
|
||||
@@ -140,17 +140,15 @@ sr_shmext_conn_remap_unlock(sr_conn_ctx_t *conn, sr_lock_mode_t mode, int ext_lo
|
||||
last = iter;
|
||||
}
|
||||
|
||||
- if (last && ((uint32_t)((char *)last - conn->ext_shm.addr) + last->size == conn->ext_shm.size)) {
|
||||
- if ((err_info = sr_file_get_size(conn->ext_shm.fd, &shm_file_size))) {
|
||||
- goto cleanup_unlock;
|
||||
- }
|
||||
+ /* cast `last` as a char* for correct pointer arithmetic. */
|
||||
+ last_hole_end = last ? ((char *)last + last->size) : NULL;
|
||||
|
||||
+ if (last_hole_end == conn->ext_shm.addr + conn->ext_shm.size) {
|
||||
/* remove the hole */
|
||||
- last_size = last->size;
|
||||
+ new_size = conn->ext_shm.size - last->size;
|
||||
sr_ext_hole_del(SR_CONN_EXT_SHM(conn), last);
|
||||
-
|
||||
/* remap (and truncate) ext SHM */
|
||||
- if ((err_info = sr_shm_remap(&conn->ext_shm, shm_file_size - last_size))) {
|
||||
+ if ((err_info = sr_shm_remap(&conn->ext_shm, new_size))) {
|
||||
goto cleanup_unlock;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
From e0f1e2480a3f69e291deed06a2626ed9b4df1662 Mon Sep 17 00:00:00 2001
|
||||
From: IrfanMohammad <irfan.haslanded@gmail.com>
|
||||
Date: Mon, 13 Jan 2025 13:46:28 +0000
|
||||
Subject: [PATCH 09/22] modinfo UPDATE sess push oper data module cache
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Maintain a list of modules whose push oper data were modified
|
||||
by the session.
|
||||
|
||||
Acquiring the global ext_lock is significantly more expensive.
|
||||
|
||||
Previously this was implemented for connections in
|
||||
3b0165d656709b5f0cd3e8debc2e55c76c73663a
|
||||
|
||||
But in sysrepo v3.x, oper push data is tied to the session and the logic
|
||||
needs to be re-introduced.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/common_types.h | 7 +++-
|
||||
src/modinfo.c | 93 ++++++++++++++++++++++++++--------------------
|
||||
src/sysrepo.c | 14 ++++++-
|
||||
3 files changed, 71 insertions(+), 43 deletions(-)
|
||||
|
||||
diff --git a/src/common_types.h b/src/common_types.h
|
||||
index 915d9196..3ce27ad4 100644
|
||||
--- a/src/common_types.h
|
||||
+++ b/src/common_types.h
|
||||
@@ -180,7 +180,12 @@ struct sr_session_ctx_s {
|
||||
char *user; /**< Session (system) user. */
|
||||
char *nacm_user; /**< Optional NACM user. If set, NACM is applied. */
|
||||
sr_error_info_t *err_info; /**< Session error information. */
|
||||
- int push_oper_data; /**< Whether the session has stored any push operational data. */
|
||||
+
|
||||
+ struct sr_oper_push_cache_s {
|
||||
+ char *name; /**< Module name whose push oper data were ever modified by this session. */
|
||||
+ int has_data; /**< Flag if there are any actual data currently. */
|
||||
+ } *oper_push_mods;
|
||||
+ uint32_t oper_push_mod_count; /**< Count of modules with modified push oper data by this session. */
|
||||
|
||||
char *orig_name; /**< Originator name used for all events sent on this session. */
|
||||
void *orig_data; /**< Originator data used for all events sent on this session. */
|
||||
diff --git a/src/modinfo.c b/src/modinfo.c
|
||||
index 7414121e..d5c27672 100644
|
||||
--- a/src/modinfo.c
|
||||
+++ b/src/modinfo.c
|
||||
@@ -322,42 +322,26 @@ sr_error_info_t *
|
||||
sr_modinfo_collect_oper_sess(sr_session_ctx_t *sess, const struct lys_module *ly_mod, struct sr_mod_info_s *mod_info)
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
- sr_mod_shm_t *mod_shm;
|
||||
- sr_mod_t *shm_mod;
|
||||
- sr_mod_oper_push_t *oper_push;
|
||||
const struct lys_module *ly_mod2;
|
||||
- uint32_t i, j;
|
||||
-
|
||||
- mod_shm = SR_CONN_MOD_SHM(sess->conn);
|
||||
-
|
||||
- /* EXT READ LOCK */
|
||||
- if ((err_info = sr_shmext_conn_remap_lock(sess->conn, SR_LOCK_READ, 1, __func__))) {
|
||||
- return err_info;
|
||||
- }
|
||||
-
|
||||
- /* go through all the SHM modules */
|
||||
- for (i = 0; i < mod_shm->mod_count; ++i) {
|
||||
- shm_mod = SR_SHM_MOD_IDX(mod_shm, i);
|
||||
+ uint32_t i;
|
||||
|
||||
- if (ly_mod && strcmp(ly_mod->name, ((char *)mod_shm) + shm_mod->name)) {
|
||||
+ /* add only the cached modules */
|
||||
+ for (i = 0; i < sess->oper_push_mod_count; ++i) {
|
||||
+ if (ly_mod && strcmp(ly_mod->name, sess->oper_push_mods[i].name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- /* go through the sessions with oper data */
|
||||
- for (j = 0; j < shm_mod->oper_push_data_count; ++j) {
|
||||
- oper_push = &((sr_mod_oper_push_t *)(sess->conn->ext_shm.addr + shm_mod->oper_push_data))[j];
|
||||
- if ((oper_push->sid == sess->sid) && oper_push->has_data) {
|
||||
- break;
|
||||
- }
|
||||
+ if (!sess->oper_push_mods[i].has_data) {
|
||||
+ continue;
|
||||
}
|
||||
|
||||
- if (j < shm_mod->oper_push_data_count) {
|
||||
- /* remember the module */
|
||||
- ly_mod2 = ly_ctx_get_module_implemented(sess->conn->ly_ctx, ((char *)mod_shm) + shm_mod->name);
|
||||
- SR_CHECK_INT_GOTO(!ly_mod2, err_info, cleanup_unlock);
|
||||
- if ((err_info = sr_modinfo_add(ly_mod2, NULL, 0, 0, mod_info))) {
|
||||
- goto cleanup_unlock;
|
||||
- }
|
||||
+ ly_mod2 = ly_ctx_get_module_implemented(sess->conn->ly_ctx, sess->oper_push_mods[i].name);
|
||||
+ if (!ly_mod2) {
|
||||
+ /* could have been removed */
|
||||
+ continue;
|
||||
+ }
|
||||
+ if ((err_info = sr_modinfo_add(ly_mod2, NULL, 0, 0, mod_info))) {
|
||||
+ return err_info;
|
||||
}
|
||||
|
||||
if (ly_mod) {
|
||||
@@ -365,11 +349,7 @@ sr_modinfo_collect_oper_sess(sr_session_ctx_t *sess, const struct lys_module *ly
|
||||
}
|
||||
}
|
||||
|
||||
-cleanup_unlock:
|
||||
- /* EXT READ UNLOCK */
|
||||
- sr_shmext_conn_remap_unlock(sess->conn, SR_LOCK_READ, 1, __func__);
|
||||
-
|
||||
- return err_info;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
sr_error_info_t *
|
||||
@@ -2664,7 +2644,7 @@ sr_modinfo_module_data_load(struct sr_mod_info_s *mod_info, struct sr_mod_info_m
|
||||
struct lyd_node *mod_data = NULL;
|
||||
const char **xpaths;
|
||||
uint32_t xpath_count;
|
||||
- int modified, has_data;
|
||||
+ int modified, has_data = 0;
|
||||
char *orig_name = NULL;
|
||||
void *orig_data = NULL;
|
||||
|
||||
@@ -2674,8 +2654,8 @@ sr_modinfo_module_data_load(struct sr_mod_info_s *mod_info, struct sr_mod_info_m
|
||||
if ((mod_info->ds == SR_DS_OPERATIONAL) && (mod_info->ds2 == SR_DS_OPERATIONAL)) {
|
||||
assert(sess);
|
||||
|
||||
- /* check whether this session even has any push oper data for this module */
|
||||
- if ((err_info = sr_shmext_oper_push_get(conn, mod->shm_mod, mod->ly_mod->name, sess->sid, NULL, &has_data,
|
||||
+ /* check whether this session even has any push oper data and next push data for this module */
|
||||
+ if (sess->oper_push_mod_count && (err_info = sr_shmext_oper_push_get(conn, mod->shm_mod, mod->ly_mod->name, sess->sid, NULL, &has_data,
|
||||
SR_LOCK_READ))) {
|
||||
return err_info;
|
||||
}
|
||||
@@ -2735,7 +2715,7 @@ sr_modinfo_module_data_load(struct sr_mod_info_s *mod_info, struct sr_mod_info_m
|
||||
/* no cached data or unusable */
|
||||
|
||||
if ((mod_info->ds == SR_DS_OPERATIONAL) && (mod_info->ds2 == SR_DS_RUNNING)) {
|
||||
- /* we need the whole runnign DS to avoid not getting parents of oper pull subscriptions and so considering
|
||||
+ /* we need the whole running DS to avoid not getting parents of oper pull subscriptions and so considering
|
||||
* them incorrectly as non-existent */
|
||||
xpaths = NULL;
|
||||
xpath_count = 0;
|
||||
@@ -3839,6 +3819,35 @@ cleanup:
|
||||
return err_info;
|
||||
}
|
||||
|
||||
+static
|
||||
+sr_error_info_t *
|
||||
+sr_modinfo_push_oper_mod_update_sess(sr_session_ctx_t *sess, const char *mod_name, int has_data)
|
||||
+{
|
||||
+ sr_error_info_t *err_info = NULL;
|
||||
+ uint32_t i;
|
||||
+ void *mem;
|
||||
+
|
||||
+ for (i = 0; i < sess->oper_push_mod_count; ++i) {
|
||||
+ if (!strcmp(sess->oper_push_mods[i].name, mod_name)) {
|
||||
+ /* already added, update has_data */
|
||||
+ sess->oper_push_mods[i].has_data = has_data;
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* add new module */
|
||||
+ mem = realloc(sess->oper_push_mods, (i + 1) * sizeof *(sess->oper_push_mods));
|
||||
+ SR_CHECK_MEM_GOTO(!mem, err_info, cleanup);
|
||||
+ sess->oper_push_mods = mem;
|
||||
+
|
||||
+ sess->oper_push_mods[i].name = strdup(mod_name);
|
||||
+ SR_CHECK_MEM_GOTO(!sess->oper_push_mods[i].name, err_info, cleanup);
|
||||
+ sess->oper_push_mods[i].has_data = has_data;
|
||||
+ ++sess->oper_push_mod_count;
|
||||
+cleanup:
|
||||
+ return err_info;
|
||||
+}
|
||||
+
|
||||
sr_error_info_t *
|
||||
sr_modinfo_data_store(struct sr_mod_info_s *mod_info, sr_session_ctx_t *session, int shmmod_session_del)
|
||||
{
|
||||
@@ -3911,12 +3920,14 @@ sr_modinfo_data_store(struct sr_mod_info_s *mod_info, sr_session_ctx_t *session,
|
||||
} else {
|
||||
/* stored oper data, update info in mod/ext SHM */
|
||||
if ((err_info = sr_shmext_oper_push_update(mod_info->conn, mod->shm_mod, mod->ly_mod->name,
|
||||
- sid, 0, mod_data ? 1 : 0, SR_LOCK_WRITE))) {
|
||||
+ sid, 0, !!mod_data, SR_LOCK_WRITE))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
- /* remember to discard the push oper data on session stop */
|
||||
- session->push_oper_data = 1;
|
||||
+ /* cache the modified module in the session */
|
||||
+ if ((err_info = sr_modinfo_push_oper_mod_update_sess(session, mod->ly_mod->name, !!mod_data))) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 614b5454..797de6aa 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -713,6 +713,7 @@ _sr_session_stop(sr_session_ctx_t *session)
|
||||
{
|
||||
sr_error_info_t *err_info = NULL, *tmp_err;
|
||||
sr_datastore_t ds;
|
||||
+ uint32_t i;
|
||||
|
||||
/* subscriptions need to be freed before, with a WRITE lock */
|
||||
assert(!session->subscription_count && !session->subscriptions);
|
||||
@@ -721,7 +722,7 @@ _sr_session_stop(sr_session_ctx_t *session)
|
||||
tmp_err = sr_session_notif_buf_stop(session);
|
||||
sr_errinfo_merge(&err_info, tmp_err);
|
||||
|
||||
- if (session->push_oper_data) {
|
||||
+ if (session->oper_push_mod_count) {
|
||||
/* free any stored operational data and the SHM ext push oper data entries */
|
||||
_sr_discard_oper_changes(session, NULL, 1, 0);
|
||||
}
|
||||
@@ -755,6 +756,13 @@ _sr_session_stop(sr_session_ctx_t *session)
|
||||
sr_release_data(session->dt[ds].edit);
|
||||
lyd_free_all(session->dt[ds].diff);
|
||||
}
|
||||
+
|
||||
+ /* free any push oper module names */
|
||||
+ for (i = 0; i < session->oper_push_mod_count; ++i) {
|
||||
+ free(session->oper_push_mods[i].name);
|
||||
+ }
|
||||
+ free(session->oper_push_mods);
|
||||
+
|
||||
sr_rwlock_destroy(&session->notif_buf.lock);
|
||||
free(session);
|
||||
|
||||
@@ -4708,6 +4716,10 @@ sr_get_oper_changes(sr_session_ctx_t *session, const char *module_name, sr_data_
|
||||
|
||||
*data = NULL;
|
||||
|
||||
+ if (!session->oper_push_mod_count) {
|
||||
+ return sr_api_ret(session, err_info);
|
||||
+ }
|
||||
+
|
||||
SR_MODINFO_INIT(mod_info, conn, SR_DS_OPERATIONAL, SR_DS_OPERATIONAL);
|
||||
|
||||
/* CONTEXT LOCK */
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
From fef86228fcb8636d53faf43b36afd92b7161162b Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Tue, 14 Jan 2025 08:53:59 +0100
|
||||
Subject: [PATCH 10/22] modinfo REFACTOR formatting and missing doxygen
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/modinfo.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/modinfo.c b/src/modinfo.c
|
||||
index d5c27672..ff6ffc40 100644
|
||||
--- a/src/modinfo.c
|
||||
+++ b/src/modinfo.c
|
||||
@@ -3819,8 +3819,15 @@ cleanup:
|
||||
return err_info;
|
||||
}
|
||||
|
||||
-static
|
||||
-sr_error_info_t *
|
||||
+/**
|
||||
+ * @brief Update push oper mod data in a session, add a new module if not yet present.
|
||||
+ *
|
||||
+ * @param[in] sess Session to update.
|
||||
+ * @param[in] mod_name Module name.
|
||||
+ * @param[in] has_data Flag to store.
|
||||
+ * @return err_info, NULL on success.
|
||||
+ */
|
||||
+static sr_error_info_t *
|
||||
sr_modinfo_push_oper_mod_update_sess(sr_session_ctx_t *sess, const char *mod_name, int has_data)
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
From a593e1c993ae4dd7aa2942aa046633c8aaeb5ee4 Mon Sep 17 00:00:00 2001
|
||||
From: Irfan <irfan.haslanded@gmail.com>
|
||||
Date: Tue, 14 Jan 2025 08:59:44 +0100
|
||||
Subject: [PATCH 11/22] shm_ext BUGFIX remap READ lock is enough (#3496)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
`sr_shmext_rpc_sub_remove_dead()` calls `sr_shmext_rpc_sub_stop()`
|
||||
which doesn't need a WRITE `ext_remap_lock`.
|
||||
|
||||
sr_shmext_recover_sub_rpc() already only acquire a READ lock.
|
||||
|
||||
Subscriptions can only be removed, which does not remap the SHM.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/shm_ext.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/shm_ext.c b/src/shm_ext.c
|
||||
index 78930469..917a049a 100644
|
||||
--- a/src/shm_ext.c
|
||||
+++ b/src/shm_ext.c
|
||||
@@ -1476,8 +1476,8 @@ sr_shmext_rpc_sub_remove_dead(sr_conn_ctx_t *conn, off_t *subs, uint32_t *sub_co
|
||||
sr_mod_rpc_sub_t *shm_sub;
|
||||
char *path = NULL;
|
||||
|
||||
- /* EXT WRITE LOCK */
|
||||
- if ((err_info = sr_shmext_conn_remap_lock(conn, SR_LOCK_WRITE, 1, __func__))) {
|
||||
+ /* EXT READ LOCK */
|
||||
+ if ((err_info = sr_shmext_conn_remap_lock(conn, SR_LOCK_READ, 1, __func__))) {
|
||||
sr_errinfo_free(&err_info);
|
||||
return;
|
||||
}
|
||||
@@ -1502,8 +1502,8 @@ sr_shmext_rpc_sub_remove_dead(sr_conn_ctx_t *conn, off_t *subs, uint32_t *sub_co
|
||||
path = NULL;
|
||||
}
|
||||
|
||||
- /* EXT WRITE UNLOCK */
|
||||
- sr_shmext_conn_remap_unlock(conn, SR_LOCK_WRITE, 1, __func__);
|
||||
+ /* EXT READ UNLOCK */
|
||||
+ sr_shmext_conn_remap_unlock(conn, SR_LOCK_READ, 1, __func__);
|
||||
}
|
||||
|
||||
sr_error_info_t *
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
From ce908d743bc9f49d5986c748dba71be194b7df89 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Tue, 14 Jan 2025 09:57:49 +0100
|
||||
Subject: [PATCH 12/22] modinfo OPTIMIZE avoid long ext lock holding
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Fixes #3497
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/modinfo.c | 77 +++++++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 47 insertions(+), 30 deletions(-)
|
||||
|
||||
diff --git a/src/modinfo.c b/src/modinfo.c
|
||||
index ff6ffc40..f969f363 100644
|
||||
--- a/src/modinfo.c
|
||||
+++ b/src/modinfo.c
|
||||
@@ -4,8 +4,8 @@
|
||||
* @brief routines for working with modinfo structure
|
||||
*
|
||||
* @copyright
|
||||
- * Copyright (c) 2018 - 2023 Deutsche Telekom AG.
|
||||
- * Copyright (c) 2018 - 2023 CESNET, z.s.p.o.
|
||||
+ * Copyright (c) 2018 - 2025 Deutsche Telekom AG.
|
||||
+ * Copyright (c) 2018 - 2025 CESNET, z.s.p.o.
|
||||
*
|
||||
* This source code is licensed under BSD 3-Clause License (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
@@ -1254,49 +1254,69 @@ sr_module_oper_data_load(struct sr_mod_info_mod_s *mod, sr_conn_ctx_t *conn, uin
|
||||
struct lyd_node **mod_oper_data, struct lyd_node **data)
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
- sr_mod_oper_push_t *oper_push;
|
||||
+ sr_mod_oper_push_t *oper_push_dup = NULL, *oper_push_ext;
|
||||
struct lyd_node *mod_data = NULL, *next, *node;
|
||||
const struct lys_module *ly_mod;
|
||||
const char *xpath;
|
||||
struct ly_set *set;
|
||||
- uint32_t i, j, merge_opts;
|
||||
- int last_sid = 0;
|
||||
+ uint32_t i, j, merge_opts, oper_push_count = 0;
|
||||
+ int last_sid = 0, dead_cid = 0;
|
||||
|
||||
/* EXT READ LOCK */
|
||||
if ((err_info = sr_shmext_conn_remap_lock(conn, SR_LOCK_READ, 1, __func__))) {
|
||||
- return err_info;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
- oper_push = (sr_mod_oper_push_t *)(conn->ext_shm.addr + mod->shm_mod->oper_push_data);
|
||||
- for (i = 0; i < mod->shm_mod->oper_push_data_count; ++i) {
|
||||
- if (!sr_conn_is_alive(oper_push[i].cid)) {
|
||||
- /* EXT READ UNLOCK */
|
||||
- sr_shmext_conn_remap_unlock(conn, SR_LOCK_READ, 1, __func__);
|
||||
-
|
||||
- /* recover oper push data of all dead connections */
|
||||
- if ((err_info = sr_shmmod_del_module_oper_data(conn, mod->ly_mod, &mod->state, mod->shm_mod, 1))) {
|
||||
- goto cleanup;
|
||||
+ if (mod->shm_mod->oper_push_data_count) {
|
||||
+ /* make a local copy of the array, with only alive connections */
|
||||
+ oper_push_dup = malloc(mod->shm_mod->oper_push_data_count * sizeof *oper_push_dup);
|
||||
+ if (!oper_push_dup) {
|
||||
+ SR_ERRINFO_MEM(&err_info);
|
||||
+ } else {
|
||||
+ oper_push_ext = (sr_mod_oper_push_t *)(conn->ext_shm.addr + mod->shm_mod->oper_push_data);
|
||||
+ for (i = 0; i < mod->shm_mod->oper_push_data_count; ++i) {
|
||||
+ if (!sr_conn_is_alive(oper_push_ext[i].cid)) {
|
||||
+ /* remember to remove the dead connections */
|
||||
+ dead_cid = 1;
|
||||
+ } else {
|
||||
+ oper_push_dup[oper_push_count] = oper_push_ext[i];
|
||||
+ ++oper_push_count;
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* EXT READ UNLOCK */
|
||||
+ sr_shmext_conn_remap_unlock(conn, SR_LOCK_READ, 1, __func__);
|
||||
+
|
||||
+ if (err_info) {
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
|
||||
- /* call the function again */
|
||||
- err_info = sr_module_oper_data_load(mod, conn, sid, mod_oper_data, data);
|
||||
+ if (dead_cid) {
|
||||
+ /* recover oper push data of all dead connections */
|
||||
+ if ((err_info = sr_shmmod_del_module_oper_data(conn, mod->ly_mod, &mod->state, mod->shm_mod, 1))) {
|
||||
goto cleanup;
|
||||
- } else if (!oper_push[i].has_data) {
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < oper_push_count; ++i) {
|
||||
+ if (!oper_push_dup[i].has_data) {
|
||||
/* no push oper data */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* push data entries are ordered */
|
||||
- assert(!i || (oper_push[i].order > oper_push[i - 1].order));
|
||||
+ assert(!i || (oper_push_dup[i].order > oper_push_dup[i - 1].order));
|
||||
|
||||
- if (oper_push[i].sid == sid) {
|
||||
+ if (oper_push_dup[i].sid == sid) {
|
||||
last_sid = 1;
|
||||
}
|
||||
if (!last_sid || !mod_oper_data) {
|
||||
/* load push oper data for the session */
|
||||
- if ((err_info = sr_module_file_data_append(mod->ly_mod, mod->ds_handle, SR_DS_OPERATIONAL, oper_push[i].cid,
|
||||
- oper_push[i].sid, NULL, 0, &mod_data))) {
|
||||
- goto cleanup_unlock;
|
||||
+ if ((err_info = sr_module_file_data_append(mod->ly_mod, mod->ds_handle, SR_DS_OPERATIONAL,
|
||||
+ oper_push_dup[i].cid, oper_push_dup[i].sid, NULL, 0, &mod_data))) {
|
||||
+ goto cleanup;
|
||||
}
|
||||
} else {
|
||||
use_mod_oper_data:
|
||||
@@ -1324,12 +1344,12 @@ use_mod_oper_data:
|
||||
|
||||
/* select the nodes to remove */
|
||||
if ((err_info = sr_lyd_find_xpath(*data, xpath, &set))) {
|
||||
- goto cleanup_unlock;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* get rid of all redundant results that are descendants of another result */
|
||||
if ((err_info = sr_xpath_set_filter_subtrees(set))) {
|
||||
- goto cleanup_unlock;
|
||||
+ goto cleanup;
|
||||
}
|
||||
|
||||
/* free all the selected subtrees */
|
||||
@@ -1346,7 +1366,7 @@ use_mod_oper_data:
|
||||
merge_opts = LYD_MERGE_WITH_FLAGS;
|
||||
}
|
||||
if ((err_info = sr_lyd_merge_module(data, mod_data, mod->ly_mod, sr_oper_data_merge_cb, NULL, merge_opts))) {
|
||||
- goto cleanup_unlock;
|
||||
+ goto cleanup;
|
||||
}
|
||||
mod_data = NULL;
|
||||
|
||||
@@ -1362,11 +1382,8 @@ use_mod_oper_data:
|
||||
goto use_mod_oper_data;
|
||||
}
|
||||
|
||||
-cleanup_unlock:
|
||||
- /* EXT READ UNLOCK */
|
||||
- sr_shmext_conn_remap_unlock(conn, SR_LOCK_READ, 1, __func__);
|
||||
-
|
||||
cleanup:
|
||||
+ free(oper_push_dup);
|
||||
lyd_free_siblings(mod_data);
|
||||
return err_info;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+1501
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,30 @@
|
||||
From 1977326b9a63bc9e1b7746dc0a5becb9b2aece26 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Tue, 14 Jan 2025 13:36:59 +0100
|
||||
Subject: [PATCH 14/22] SOVERSION bump to version 7.29.13
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 7d49cedb..040d2242 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -62,7 +62,7 @@ set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_
|
||||
# with backward compatible change and micro version is connected with any internal change of the library.
|
||||
set(SYSREPO_MAJOR_SOVERSION 7)
|
||||
set(SYSREPO_MINOR_SOVERSION 29)
|
||||
-set(SYSREPO_MICRO_SOVERSION 12)
|
||||
+set(SYSREPO_MICRO_SOVERSION 13)
|
||||
set(SYSREPO_SOVERSION_FULL ${SYSREPO_MAJOR_SOVERSION}.${SYSREPO_MINOR_SOVERSION}.${SYSREPO_MICRO_SOVERSION})
|
||||
set(SYSREPO_SOVERSION ${SYSREPO_MAJOR_SOVERSION})
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
From df88c15e014d75dbd6e48d4ff1291fb6068f296d Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Tue, 14 Jan 2025 13:37:09 +0100
|
||||
Subject: [PATCH 15/22] VERSION bump to version 3.4.1
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 040d2242..7b86c0f3 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -54,7 +54,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
|
||||
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
|
||||
set(SYSREPO_MAJOR_VERSION 3)
|
||||
set(SYSREPO_MINOR_VERSION 4)
|
||||
-set(SYSREPO_MICRO_VERSION 0)
|
||||
+set(SYSREPO_MICRO_VERSION 1)
|
||||
set(SYSREPO_VERSION ${SYSREPO_MAJOR_VERSION}.${SYSREPO_MINOR_VERSION}.${SYSREPO_MICRO_VERSION})
|
||||
|
||||
# Version of the library
|
||||
--
|
||||
2.43.0
|
||||
|
||||
+13
-9
@@ -1,20 +1,24 @@
|
||||
From e8daa7e3e6d24e66e1a74b00237af4c32438cb92 Mon Sep 17 00:00:00 2001
|
||||
From 401c5b8ccce07b84e3b364283a8c789908f62f01 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Tue, 28 Mar 2023 10:37:53 +0200
|
||||
Subject: [PATCH 1/7] sysrepo-plugind: add support for running in foreground
|
||||
Subject: [PATCH 16/22] sysrepo-plugind: add support for running in foreground
|
||||
with syslog
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/executables/sysrepo-plugind.c | 10 +++++++++-
|
||||
1 file changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/executables/sysrepo-plugind.c b/src/executables/sysrepo-plugind.c
|
||||
index a6a817cc..5baebec3 100644
|
||||
index 3b66cfa6..c531ca60 100644
|
||||
--- a/src/executables/sysrepo-plugind.c
|
||||
+++ b/src/executables/sysrepo-plugind.c
|
||||
@@ -98,6 +98,7 @@ help_print(void)
|
||||
@@ -100,6 +100,7 @@ help_print(void)
|
||||
" Change verbosity to a level (none, error, warning, info, debug) or\n"
|
||||
" number (0, 1, 2, 3, 4).\n"
|
||||
" -d, --debug Debug mode - is not daemonized and logs to stderr instead of syslog.\n"
|
||||
@@ -22,7 +26,7 @@ index a6a817cc..5baebec3 100644
|
||||
" -P, --plugin-install <path>\n"
|
||||
" Install a sysrepo-plugind plugin. The plugin is simply copied\n"
|
||||
" to the designated plugin directory.\n"
|
||||
@@ -201,6 +202,8 @@ daemon_init(int debug, sr_log_level_t log_level)
|
||||
@@ -214,6 +215,8 @@ daemon_init(int debug, sr_log_level_t log_level)
|
||||
|
||||
if (debug) {
|
||||
handle_signals();
|
||||
@@ -31,7 +35,7 @@ index a6a817cc..5baebec3 100644
|
||||
sr_log_stderr(log_level);
|
||||
return;
|
||||
}
|
||||
@@ -241,6 +244,7 @@ daemon_init(int debug, sr_log_level_t log_level)
|
||||
@@ -254,6 +257,7 @@ daemon_init(int debug, sr_log_level_t log_level)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
@@ -39,7 +43,7 @@ index a6a817cc..5baebec3 100644
|
||||
/* set verbosity */
|
||||
sr_log_syslog("sysrepo-plugind", log_level);
|
||||
}
|
||||
@@ -466,6 +470,7 @@ main(int argc, char **argv)
|
||||
@@ -479,6 +483,7 @@ main(int argc, char **argv)
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"verbosity", required_argument, NULL, 'v'},
|
||||
{"debug", no_argument, NULL, 'd'},
|
||||
@@ -47,7 +51,7 @@ index a6a817cc..5baebec3 100644
|
||||
{"plugin-install", required_argument, NULL, 'P'},
|
||||
{"pid-file", required_argument, NULL, 'p'},
|
||||
{"fatal-plugin-fail", no_argument, NULL, 'f'},
|
||||
@@ -474,7 +479,7 @@ main(int argc, char **argv)
|
||||
@@ -487,7 +492,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* process options */
|
||||
opterr = 0;
|
||||
@@ -56,7 +60,7 @@ index a6a817cc..5baebec3 100644
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
version_print();
|
||||
@@ -506,6 +511,9 @@ main(int argc, char **argv)
|
||||
@@ -519,6 +524,9 @@ main(int argc, char **argv)
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
+30
-17
@@ -1,7 +1,10 @@
|
||||
From 936d4f34a12ef1a2fe3372df051b77ea19ce5d59 Mon Sep 17 00:00:00 2001
|
||||
From 6cba2363b8d3a56755365f59af7830f5bd25824a Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Tue, 7 May 2024 15:41:53 +0200
|
||||
Subject: [PATCH 2/7] Allow SR_EV_DONE to return any error to sysrepocfg
|
||||
Subject: [PATCH 17/22] Allow SR_EV_DONE to return any error to sysrepocfg
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Importing a system configuration with sysrepocfg the model callbacks do
|
||||
@@ -17,17 +20,18 @@ This patch is a clumsy way of forcing the (first) error to bubble up to
|
||||
the surface and cause a non-zero exit code from sysrepocfg.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/shm_sub.c | 36 ++++++++++++++++++++++++++++--------
|
||||
src/shm_sub.h | 2 +-
|
||||
src/sysrepo.c | 2 +-
|
||||
3 files changed, 30 insertions(+), 10 deletions(-)
|
||||
src/sysrepo.c | 4 ++--
|
||||
3 files changed, 31 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/shm_sub.c b/src/shm_sub.c
|
||||
index 000f5906..4c59cbbf 100644
|
||||
index fd6f105b..588cce09 100644
|
||||
--- a/src/shm_sub.c
|
||||
+++ b/src/shm_sub.c
|
||||
@@ -1659,7 +1659,7 @@ cleanup:
|
||||
@@ -1766,7 +1766,7 @@ cleanup:
|
||||
|
||||
sr_error_info_t *
|
||||
sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *orig_name, const void *orig_data,
|
||||
@@ -36,7 +40,7 @@ index 000f5906..4c59cbbf 100644
|
||||
{
|
||||
sr_error_info_t *err_info = NULL;
|
||||
struct sr_mod_info_mod_s *mod = NULL;
|
||||
@@ -1791,12 +1791,19 @@ sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *
|
||||
@@ -1911,12 +1911,19 @@ sr_shmsub_change_notify_change_done(struct sr_mod_info_s *mod_info, const char *
|
||||
sr_rwunlock(&nsub->sub_shm->lock, 0, SR_LOCK_WRITE, cid, __func__);
|
||||
nsub->lock = SR_LOCK_NONE;
|
||||
|
||||
@@ -44,7 +48,7 @@ index 000f5906..4c59cbbf 100644
|
||||
- sr_errinfo_free(&nsub->cb_err_info);
|
||||
-
|
||||
SR_LOG_DBG("EV ORIGIN: \"%s\" \"%s\" ID %" PRIu32 " priority %" PRIu32 " succeeded.",
|
||||
nsub->mod->ly_mod->name, sr_ev2str(SR_SUB_EV_DONE), nsub->mod->request_id, nsub->cur_priority);
|
||||
nsub->mod->ly_mod->name, sr_ev2str(SR_SUB_EV_DONE), mod_info->operation_id, nsub->cur_priority);
|
||||
|
||||
+ /*
|
||||
+ * unexpected critical error, merge and cleanup, let
|
||||
@@ -59,7 +63,7 @@ index 000f5906..4c59cbbf 100644
|
||||
nsub->pending_event = 0;
|
||||
}
|
||||
} while (1);
|
||||
@@ -3278,7 +3285,7 @@ sr_shmsub_change_listen_relock(sr_sub_shm_t *sub_shm, sr_lock_mode_t mode, struc
|
||||
@@ -3424,7 +3431,7 @@ sr_shmsub_change_listen_relock(sr_sub_shm_t *sub_shm, sr_lock_mode_t mode, struc
|
||||
sr_error_info_t *
|
||||
sr_shmsub_change_listen_process_module_events(struct modsub_change_s *change_subs, sr_conn_ctx_t *conn)
|
||||
{
|
||||
@@ -68,7 +72,7 @@ index 000f5906..4c59cbbf 100644
|
||||
uint32_t i, data_len = 0, valid_subscr_count;
|
||||
char *data = NULL, *shm_data_ptr;
|
||||
int ret = SR_ERR_OK, filter_valid;
|
||||
@@ -3406,6 +3413,11 @@ process_event:
|
||||
@@ -3553,6 +3560,11 @@ process_event:
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -80,7 +84,7 @@ index 000f5906..4c59cbbf 100644
|
||||
}
|
||||
|
||||
/* subscription processed this event */
|
||||
@@ -3438,6 +3450,11 @@ process_event:
|
||||
@@ -3585,6 +3597,11 @@ process_event:
|
||||
}
|
||||
break;
|
||||
case SR_SUB_EV_DONE:
|
||||
@@ -92,7 +96,7 @@ index 000f5906..4c59cbbf 100644
|
||||
case SR_SUB_EV_ABORT:
|
||||
/* nothing to do */
|
||||
break;
|
||||
@@ -3457,14 +3474,17 @@ process_event:
|
||||
@@ -3604,14 +3621,17 @@ process_event:
|
||||
|
||||
/* SUB WRITE URGE LOCK */
|
||||
if (sr_shmsub_change_listen_relock(sub_shm, SR_LOCK_WRITE_URGE, &sub_info, change_sub, change_subs->module_name,
|
||||
@@ -112,7 +116,7 @@ index 000f5906..4c59cbbf 100644
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -3953,7 +3973,7 @@ finish_iter:
|
||||
@@ -4101,7 +4121,7 @@ finish_iter:
|
||||
sr_errinfo_free(&cb_err_info);
|
||||
|
||||
/* publish "done" event */
|
||||
@@ -122,7 +126,7 @@ index 000f5906..4c59cbbf 100644
|
||||
}
|
||||
|
||||
diff --git a/src/shm_sub.h b/src/shm_sub.h
|
||||
index 62050e98..04637223 100644
|
||||
index 505dab39..617a88b7 100644
|
||||
--- a/src/shm_sub.h
|
||||
+++ b/src/shm_sub.h
|
||||
@@ -144,7 +144,7 @@ sr_error_info_t *sr_shmsub_change_notify_change(struct sr_mod_info_s *mod_info,
|
||||
@@ -135,15 +139,24 @@ index 62050e98..04637223 100644
|
||||
/**
|
||||
* @brief Notify about (generate) a change "abort" event.
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 06428bd8..3f08a627 100644
|
||||
index 97537207..a1bbc61f 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -3913,7 +3913,7 @@ store:
|
||||
@@ -3994,7 +3994,7 @@ sr_error_info_t *
|
||||
sr_changes_notify_store(struct sr_mod_info_s *mod_info, sr_session_ctx_t *session, int shmmod_session_del,
|
||||
uint32_t timeout_ms, sr_error_info_t **err_info2)
|
||||
{
|
||||
- sr_error_info_t *err_info = NULL;
|
||||
+ sr_error_info_t *err_info = NULL, *cb_err_info = NULL;
|
||||
struct sr_denied denied = {0};
|
||||
sr_lock_mode_t change_sub_lock = SR_LOCK_NONE;
|
||||
uint32_t sid = 0, err_count;
|
||||
@@ -4141,7 +4141,7 @@ store:
|
||||
}
|
||||
|
||||
/* publish "done" event, all changes were applied */
|
||||
- if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms))) {
|
||||
+ if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, cb_err_info))) {
|
||||
+ if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, &cb_err_info))) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+8
-4
@@ -1,18 +1,22 @@
|
||||
From e518c0ee5b4a328c5cbc7e7f25d329d094183798 Mon Sep 17 00:00:00 2001
|
||||
From e328151d027e408befb8b941418f84e2909f92e6 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Wed, 8 May 2024 17:00:50 +0200
|
||||
Subject: [PATCH 3/7] Allow to copy from factory default
|
||||
Subject: [PATCH 18/22] Allow to copy from factory default
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/sysrepo.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 3f08a627..3b11c0b8 100644
|
||||
index a1bbc61f..22ee9fe4 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -4161,7 +4161,7 @@ sr_copy_config(sr_session_ctx_t *session, const char *module_name, sr_datastore_
|
||||
@@ -4535,7 +4535,7 @@ sr_copy_config(sr_session_ctx_t *session, const char *module_name, sr_datastore_
|
||||
struct sr_mod_info_s mod_info;
|
||||
const struct lys_module *ly_mod = NULL;
|
||||
|
||||
+11
-6
@@ -1,11 +1,16 @@
|
||||
From a7e91aac7d7669c6b82cb06a1b4e3c3e3d79275f Mon Sep 17 00:00:00 2001
|
||||
From f833cf10647b0c76386fe0850011204a321bb0d9 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Mattias=20Walstr=C3=B6m?= <lazzer@gmail.com>
|
||||
Date: Mon, 6 May 2024 14:49:32 +0200
|
||||
Subject: [PATCH 4/7] Add -z switch to sysrepoctl to install factory config
|
||||
Subject: [PATCH 19/22] Add -z switch to sysrepoctl to install factory config
|
||||
from a json file
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
This to be able to load the yang modules during build time instead on boot.
|
||||
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/executables/sysrepoctl.c | 20 +++++++++++++--
|
||||
src/lyd_mods.h | 7 ++++++
|
||||
@@ -84,10 +89,10 @@ index 1960bc06..a8ca5add 100644
|
||||
+
|
||||
#endif
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 3b11c0b8..2e02de39 100644
|
||||
index 22ee9fe4..518f34e6 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -1646,6 +1646,55 @@ sr_free_int_install_mods(sr_int_install_mod_t *new_mods, uint32_t new_mod_count)
|
||||
@@ -1621,6 +1621,55 @@ sr_free_int_install_mods(sr_int_install_mod_t *new_mods, uint32_t new_mod_count)
|
||||
free(new_mods);
|
||||
}
|
||||
|
||||
@@ -144,7 +149,7 @@ index 3b11c0b8..2e02de39 100644
|
||||
sr_install_module(sr_conn_ctx_t *conn, const char *schema_path, const char *search_dirs, const char **features)
|
||||
{
|
||||
diff --git a/src/sysrepo.h b/src/sysrepo.h
|
||||
index 8a6a70b8..41c9e52b 100644
|
||||
index 6881830d..0280244a 100644
|
||||
--- a/src/sysrepo.h
|
||||
+++ b/src/sysrepo.h
|
||||
@@ -34,7 +34,6 @@ extern "C" {
|
||||
@@ -155,7 +160,7 @@ index 8a6a70b8..41c9e52b 100644
|
||||
/**
|
||||
* @defgroup log_api Logging API
|
||||
* @{
|
||||
@@ -708,6 +707,15 @@ int sr_get_module_info(sr_conn_ctx_t *conn, sr_data_t **sysrepo_data);
|
||||
@@ -717,6 +716,15 @@ int sr_get_module_info(sr_conn_ctx_t *conn, sr_data_t **sysrepo_data);
|
||||
*/
|
||||
int sr_is_module_internal(const struct lys_module *ly_mod);
|
||||
|
||||
+9
-5
@@ -1,7 +1,10 @@
|
||||
From a4060077214c573f34f2a82b18083ccd27600a38 Mon Sep 17 00:00:00 2001
|
||||
From fa14b6da3db9cf08d10108ce95fdfaecf7f76bf7 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Wed, 21 Aug 2024 16:00:35 +0200
|
||||
Subject: [PATCH 5/7] Introduce new log level [SEC] for audit trails
|
||||
Subject: [PATCH 20/22] Introduce new log level [SEC] for audit trails
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
This adds a new log level for security and audit trail related log
|
||||
@@ -19,6 +22,7 @@ system log daemon, dropping any [SEVERITY] prefix. Also, \n is most
|
||||
often dropped by log daemons.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/log.c | 18 +++++++++++++++++-
|
||||
src/log.h | 1 +
|
||||
@@ -70,10 +74,10 @@ index e15055ac..25eab8fa 100644
|
||||
|
||||
/* logging callback */
|
||||
diff --git a/src/log.h b/src/log.h
|
||||
index d7e65b88..8722e51d 100644
|
||||
index 9a60f1f6..acd7eead 100644
|
||||
--- a/src/log.h
|
||||
+++ b/src/log.h
|
||||
@@ -32,6 +32,7 @@
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#define SR_LOG_WRN(...) sr_log(SR_LL_WRN, __VA_ARGS__)
|
||||
#define SR_LOG_INF(...) sr_log(SR_LL_INF, __VA_ARGS__)
|
||||
@@ -82,7 +86,7 @@ index d7e65b88..8722e51d 100644
|
||||
|
||||
#define SR_CHECK_MEM_GOTO(cond, err_info, go) if (cond) { SR_ERRINFO_MEM(&(err_info)); goto go; }
|
||||
diff --git a/src/sysrepo_types.h b/src/sysrepo_types.h
|
||||
index 9f820b84..9a0de2be 100644
|
||||
index 337ee51a..bec7317d 100644
|
||||
--- a/src/sysrepo_types.h
|
||||
+++ b/src/sysrepo_types.h
|
||||
@@ -65,7 +65,8 @@ typedef enum {
|
||||
+12
-8
@@ -1,7 +1,10 @@
|
||||
From 3ee457861d98c62b2659b4fa49ec4571e78c83d4 Mon Sep 17 00:00:00 2001
|
||||
From 0c28a5f1c99d8fe200f23647cf06ba640e767166 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Wed, 21 Aug 2024 16:04:43 +0200
|
||||
Subject: [PATCH 6/7] Add audit trail for high priority system changes
|
||||
Subject: [PATCH 21/22] Add audit trail for high priority system changes
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
Committing a change to running, copying to a datastore, or calling an
|
||||
@@ -13,15 +16,16 @@ is when the system actually activates the changes. Copying to startup
|
||||
or other datastores is handled separately.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/sysrepo.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
diff --git a/src/sysrepo.c b/src/sysrepo.c
|
||||
index 2e02de39..85a8e41c 100644
|
||||
index 518f34e6..a7e6563a 100644
|
||||
--- a/src/sysrepo.c
|
||||
+++ b/src/sysrepo.c
|
||||
@@ -3961,6 +3961,9 @@ store:
|
||||
@@ -4189,6 +4189,9 @@ store:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@@ -29,9 +33,9 @@ index 2e02de39..85a8e41c 100644
|
||||
+ SR_LOG_SEC("user \"%s\" commiting changes to %s ...", session->nacm_user, sr_ds2str(mod_info->ds));
|
||||
+
|
||||
/* publish "done" event, all changes were applied */
|
||||
if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, cb_err_info))) {
|
||||
if ((err_info = sr_shmsub_change_notify_change_done(mod_info, orig_name, orig_data, timeout_ms, &cb_err_info))) {
|
||||
goto cleanup;
|
||||
@@ -3972,6 +3975,9 @@ store:
|
||||
@@ -4200,6 +4203,9 @@ store:
|
||||
}
|
||||
|
||||
cleanup:
|
||||
@@ -41,7 +45,7 @@ index 2e02de39..85a8e41c 100644
|
||||
if (change_sub_lock) {
|
||||
assert(change_sub_lock == SR_LOCK_READ);
|
||||
|
||||
@@ -4300,6 +4306,9 @@ sr_copy_config(sr_session_ctx_t *session, const char *module_name, sr_datastore_
|
||||
@@ -4671,6 +4677,9 @@ sr_copy_config(sr_session_ctx_t *session, const char *module_name, sr_datastore_
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +55,7 @@ index 2e02de39..85a8e41c 100644
|
||||
cleanup:
|
||||
/* MODULES UNLOCK */
|
||||
sr_shmmod_modinfo_unlock(&mod_info);
|
||||
@@ -6580,6 +6589,9 @@ sr_rpc_send_tree(sr_session_ctx_t *session, struct lyd_node *input, uint32_t tim
|
||||
@@ -7132,6 +7141,9 @@ sr_rpc_send_tree(sr_session_ctx_t *session, struct lyd_node *input, uint32_t tim
|
||||
}
|
||||
}
|
||||
|
||||
+10
-14
@@ -1,7 +1,10 @@
|
||||
From be7579a3a787d7089acbda7536a21a2a9edc487d Mon Sep 17 00:00:00 2001
|
||||
From 72be8d7e245fe8cd30bd1e2b5d308aacbf0f7b07 Mon Sep 17 00:00:00 2001
|
||||
From: Joachim Wiberg <troglobit@gmail.com>
|
||||
Date: Fri, 23 Aug 2024 12:22:06 +0200
|
||||
Subject: [PATCH 7/7] On error in sr_shmsub_listen_thread(), exit process
|
||||
Subject: [PATCH 22/22] On error in sr_shmsub_listen_thread(), exit process
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
Organization: Addiva Elektronik
|
||||
|
||||
If processing callback events in, e.g., sysrepo-plugind, make sure to
|
||||
@@ -9,23 +12,16 @@ log the error and exit(1) the entire process so the system can decide
|
||||
to handle the problem. For example, restart all dependent services.
|
||||
|
||||
Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
|
||||
Signed-off-by: Mattias Walström <lazzer@gmail.com>
|
||||
---
|
||||
src/shm_sub.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
src/shm_sub.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/shm_sub.c b/src/shm_sub.c
|
||||
index 4c59cbbf..3d703cac 100644
|
||||
index 588cce09..07d8960f 100644
|
||||
--- a/src/shm_sub.c
|
||||
+++ b/src/shm_sub.c
|
||||
@@ -4825,6 +4825,7 @@ sr_shmsub_listen_thread(void *arg)
|
||||
* another event is generated, our event pipe will not get notified */
|
||||
continue;
|
||||
} else if (ret) {
|
||||
+ SR_LOG_WRN("failed sr_subscription_process_events(), ret:%d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -4865,5 +4866,7 @@ error:
|
||||
@@ -4987,5 +4987,7 @@ error:
|
||||
/* free our own resources */
|
||||
ATOMIC_STORE_RELAXED(subscr->thread_running, 0);
|
||||
pthread_detach(pthread_self());
|
||||
Reference in New Issue
Block a user