local ARS#4
Open
VladimirKuk wants to merge 84 commits into
Open
Conversation
Update start.sh for new sonic-swss soft bfd tests
Added ICMP Echo hardware offload session table names
) Support new OPs for stats stream telemetry capability query: https://github.com/opencomputeproject/SAI/blob/d158311e4f239f0f9f8cabab073a10dbab82a848/inc/saiobject.h#L308-L319 Signed-off-by: Ze Gan <ganze718@gmail.com>
* add more ha appl state table name * same table name for npu/dpu * address comment --------- Co-authored-by: Saikrishna Arcot <sarcot@microsoft.com>
…ails due to Redis loading the dataset. (sonic-net#986) Enhance swss-common logging by writing a warning log when a command fails due to Redis loading the dataset. Why I did it Fix issue sonic-net/sonic-buildimage#17472 sonic-db-cli write error log, this is because sonic-db-cli execute PING command when Redis is loading dataset. How I did it When command failed because Redis is loading dataset, write warning log instead of error log. Description for the changelog Enhance swss-common logging by writing a warning log when a command fails due to Redis loading the dataset.
Becuase we see error message "This is a scheduled Ubuntu 20.04 retirement. Ubuntu 20.04 LTS runner will be removed on 2025-04-15. For more details, see actions/runner-images#11101".
Add new tables for SRv6 counters support
…ic-net#1009) Adding a table to store peer info if peer creation is successful. This document explains the need for this table and the data that will go into it: https://github.com/sonic-net/SONiC/pull/1963/files
…lding 20.04 (sonic-net#1018) The test failure is due to VS test failure of inter-dependency.
What I did Added the COPP_TRAP_CAPABILITY_TABLE table definition to schema.h Why I did it Details in HLD: sonic-net/SONiC#1943
…_tracker (sonic-net#1016) Add table definitions for bgp_session_tracker and link_state_tracker in STATE_DB. Note: The TABLE suffix is added in accordance with the schema.h naming conventions.
This is to reopen sonic-net#991 The rust code using swss-common needs to access redis instances from different containers and namespaces.
Limit grabbed libyang libraries to only v1. Upgrading to libyang v3 (sonic-net/sonic-buildimage#21679) is causing the swss-common pipeline build to fail. The pipeline assumes that any package starting with libyang_ or libyang- is a libyang v1 package and tries to install it. However, the dev header package for libyang v3 starts with libyang-, so the pipeline tries to download/install it as well, which causes the build to fail since it depends on the base libyang v3 package which is not grabbed because it starts with libyang3.
Add new table names as per sonic-net/SONiC#2015
…onic-net/sonic-dash-ha (sonic-net#1044) Move swss-common/swss-common-testing crates from https://github.com/sonic-net/sonic-dash-ha
…-net#1052) This PR is a partial duplicate of sonic-net/sonic-dash-ha#84 Since crates/swss-common will be moved in this repo. why During investigating issue sonic-net#75, I created test case to verify zmq behaviour in handling no connection and connection loss. It is found that with the current swss-common zmq implementation with below attributes, we don't need to handle reconnect explicitly. PUSH/PULL model ZMQ_IMMEDIATE = 0 (default) ZMQ_SNDHWM = 10000 what this PR does add unit test for zmq late connect and reconnect for regression remove unneeded code for falling back to ProducerStateTable in test environment since zmq client won't fail if zmq server is not connected. update test_utils/README.md with missing argument to start redis in test environment
Moving SonicDbTable to sonic-dash-ha as part of sonic-net/sonic-dash-ha#82
Make some changes to fix compilation for Debian Trixie. This includes: Don't mark m_buffer as const, since the memory that it's pointing to is anyways modified by BinarySerializer. Add support for compiling with libhiredis 1.1.0. Add a missing include for <stdexcept>. Use SWIG_AppendOutput instead of SWIG_Python_AppendOutput, as the latter now takes another parameter to indicate if the function's return type is void, and the recommendation appears to be to just use SWIG_AppendOutput. Add a workaround for GCC complaining about attributes being ignored in a template argument when passing in pclose as a function pointer into std::unique_ptr.[1] [1] This is based on https://stackoverflow.com/a/76867913
Why I did it To enable YANG based CFG table generation, the ConfigDB related macro will be generated by YANG model How I did it Add gen_cfg_schema.py script to generate cfg_schema.h which will be included in schema.h Work item tracking Microsoft ADO: 31676863 How to verify it make deb build
why SonicDBConfig::initializeGlobalConfig aborts parsing global config if it encounters an include of a database config that doesn't exist. The global config file includes all possible includes in the switch. However, not all includes are relevant to a client. For example, in smartswitch, dash-ha container only cares NPU databases and databases of the DPU managed by the container. The current behavior requires a dash-ha container mounting all the DPU database instances. what this PR does Add ignore_nonexistent flag, with default value false, to function parseDatabaseConfig. If it is set to true, it will not throw error if the included database config file doesn't exist. initializeGlobalConfig sets ignore_nonexistent to true when calling parseDatabaseConfig. If inst_entry, db_entry and separator_entry are empty, it will ignore the key.
…ic-net#1062) This PR adds c-api/Rust wrappers for ConfigDBConnector and EventPublisher, so they will be available for Rust application development. Also add unit tests for c-api and Rust wrappers.
…les (sonic-net#1138) When building the team kernel module (and others), if a matching source kernel version exists, then make sure we use that exact version. This avoids the case where we end up pulling the sources for a newer kernel version when a matching one exists. Signed-off-by: Saikrishna Arcot <sarcot@microsoft.com>
Signed-off-by: dhanasekar-arista <dhanasekar@arista.com>
why I did it unwrap() and expect function may crash at runtime. For the issues that may happen, we should catch the error and handle it gracefully instead of crashing. This PR focuses unwrap calls in types.rs How I did it Return error if it fails to convert c-type string to rust str. For the case of take-style functions, such as take_cstr, it will continue the operation and free the memory then return the error. This is to avoid memory leak. Ideally, the functions should act atomically. If it fails, it leaves input intact. However, it requires copy memory or scan twice, which is not efficient for some very rare error and the caller needs to free the memory anyway.
* fix sonic slave name Signed-off-by: yijingyan2 <yijingyan@microsoft.com>
…c-net#1147) Signed-off-by: Rustiqly <rustiqly@users.noreply.github.com> Co-authored-by: Rustiqly <rustiqly@users.noreply.github.com>
For the CI runner, install the python3 redis package from the Ubuntu repos instead of via pip. This has the advantage of the version being fixed for the Debian version the test runner is using. Also remove some development package installations, which shouldn't be needed for running these tests. This works around the regression for Unix sockets introduced in redis 7.2.0 (see also redis/redis-py#3957 and redis/redis-py#3957).
[DPU] Add support for Flow API
* Add new schema for Counter and Flex Counter Databases [DPU] Add support for HA Set Counters
Signed-off-by: Apoorv Sachan <apoorv@arista.com>
These changes are brought in sonic-swss-common to support the collection
of following attributes:
1 - SAI_PORT_SERDES_ATTR_RX_VGA (type : sai_u32_list_t)
2 - SAI_PORT_SERDES_ATTR_TX_FIR_TAPS_LIST (type : sai_taps_list_t )
(both under sai_port_serdes_attr_t)
Changes adds definion for:
1 - COUNTERS_PORT_SERDES_ID_TO_PORT_ID_MAP
It Stores the mapping between port-serdes-vid to port-vid.
This mapping is updated during port initialization, port
de-initialization, and also when port-serdes related config is changed
for a port.
We need to keep this mapping for PHY PORT SERDES ATTR counter collection
when syncd write to COUNTERS_DB::PORT_PHY_ATTR: to find appropriate
mapping from port-serdes-vid to port-vid.
ex: $ sonic-db-cli COUNTERS_DB hgetall "COUNTERS_PORT_SERDES_ID_TO_PORT_ID_MAP"
{'oid:0x57000000001696': 'oid:0x1000000000061', 'oid:0x57000000001697': 'oid:0x1000000000035', < … >}
2 - PORT_PHY_SERDES_ATTR_ID_LIST
Related to FLEX_COUNTER_DB::FLEX_COUNTER_TABLE:PORT_PHY_SERDES_ATTR: to
store the attributes that needs to be collected for each port.
ex: $ sonic-db-cli FLEX_COUNTER_DB hgetall "FLEX_COUNTER_TABLE:PORT_PHY_SERDES_ATTR:oid:0x5700000000170a"
{'PORT_PHY_SERDES_ATTR_ID_LIST': 'SAI_PORT_SERDES_ATTR_TX_FIR_TAPS_LIST,SAI_PORT_SERDES_ATTR_RX_VGA'}
Signed-off-by: Prajjwal Singh <prajjwal@arista.com>
Signed-off-by: mint570 <runmingwu@google.com> Co-authored-by: mint570 <runmingwu@google.com>
Signed-off-by: divyagayathri-hcl <divyagayathri.s@hcl.com> Co-authored-by: mint570 <runmingwu@google.com>
…l build (sonic-net#1168) Signed-off-by: Yijing Yan <yijingyan@microsoft.com>
When a DPU is powered off and back on, the ZMQ client on the switch still holds a stale TCP connection. The first message sent after DPU restart is delivered over the dead connection, gets a TCP RST, and is silently lost. ZMQ then auto-reconnects, so subsequent messages succeed. This patch enables: TCP keepalive on ZmqClient PUSH sockets to detect dead connections proactively (within ~10 seconds of peer going down). TCP keepalive on ZmqServer PULL sockets as defense-in-depth. With these changes, after DPU power-off: TCP keepalive probes will fail, causing ZMQ to tear down the stale connection and reconnect
…onic-net#1167) The constructor allocates m_link_cache via rtnl_link_alloc_cache() but the destructor only frees the socket. Add nl_cache_free() call before freeing the socket to prevent memory leak. Fixes: sonic-net#1165 Signed-off-by: Rustiqly <rustiqly@users.noreply.github.com> Co-authored-by: Rustiqly <rustiqly@users.noreply.github.com>
Define a table name to hold the mapping for OID to ENI name (reverse mapping of the existing COUNTERS_ENI_NAME_MAP) Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
… support (sonic-net#1155) Why I did it This PR adds infrastructure support in sonic-swss-common for EVPN Multi-Homing (EVPN-MH) feature. EVPN-MH requires: A new L2 nexthop group table to manage L2 nexthop groups in APPL_DB Raw netlink message handling capability to process EVPN-MH specific netlink attributes that cannot be fully parsed by libnl's generic object parsing Work item tracking Microsoft ADO (number only): How I did it Added new APPL_DB table: APP_L2_NEXTHOP_GROUP_TABLE_NAME for managing L2 nexthop groups Implemented raw netlink message handler infrastructure in NetDispatcher: Added registerRawMessageHandler() to register callbacks for raw netlink messages Added unregisterRawMessageHandler() to unregister raw message handlers Added onNetlinkMessageRaw() to handle raw netlink messages (as nlmsghdr*) Added onMsgRaw() virtual method in NetMsg class for derived classes to implement raw message processing Added m_rawhandlers map to store raw message handlers Modified message flow: When a netlink message is not handled by the regular (parsed) handlers, it falls back to raw message handlers This allows components to choose between: Parsed netlink messages (existing behavior via onMsg() with nl_object*) Raw netlink messages (new capability via onMsgRaw() with nlmsghdr*) How to verify it Build sonic-swss-common with these changes Verify that existing netlink message handling continues to work (backward compatibility) Test EVPN-MH feature components that register raw message handlers Verify L2_NEXTHOP_GROUP_TABLE can be accessed from APPL_DB Description for the changelog Add support for L2 nexthop group table and raw netlink message handling for EVPN-MH feature Link to config_db schema for YANG module changes N/A - This PR only adds APPL_DB table definition, no CONFIG_DB schema changes
be2ac51 to
ebfcc6b
Compare
Added LLR APPL_DB table names to schema Why I did it HLD: sonic-net/SONiC#2098 How I verified it Verified sonic-swss compilation and DVS tests with this change .
Signed-off-by: prashanth-nexthop <prashanth@nexthop.ai>
…te CI
Port the YANG schema-walking code in defaultvalueprovider.{h,cpp} from
libyang1 to libyang3. sonic-swss-common is a submodule whose libyang
dependency is pinned by the parent project (sonic-buildimage), so the
source needs to compile against either version. Use LY_ARRAY_COUNT
(defined only by libyang3) as a preprocessor sentinel:
* Trivial spelling/accessor differences (node types, ->child,
leaf->dflt extraction, module->data layout, ly_ctx_destroy,
ly_ctx_load_module) are hidden behind SWSS_LYS_* macros so the
call sites stay near-identical to the libyang1 source.
* Structurally divergent code (list-key extraction via lysc_is_key,
leaf-list default values, the ly_ctx_new return-by-out-param
signature) still needs explicit #ifdef branches.
SWIG's preprocessor cannot see <libyang/libyang.h>, so when it parses
defaultvalueprovider.h it always takes the libyang1 branch of the
version shim and generates wrappers that fail to compile against
libyang3 headers. `%ignore swss::DefaultValueHelper` in
pyext/swsscommon.i suppresses those wrappers (the helper is internal —
no Python or Go caller uses it) and keeps the generated bindings
version-agnostic.
CI changes wired up for the libyang3 packages:
* Switch the .deb download/install patterns from libyang1
(libyang_1.0*, libyang-*_1.0*, libyang-cpp_*, python3-yang_*) to
libyang3 (libyang3_*, libyang-dev_3*) across azure-pipelines.yml
and the build/sairedis/swss/test-docker templates so CI pulls the
libyang3 artifacts the parent project produces.
* In the amd64/ubuntu-22.04 host job, replace the python3-libyang
.deb install with `pip install libyang==3.3.0`. The bookworm-
built python3-libyang_3.1.0 .deb pins python3 (>= 3.11~,
<< 3.12) so it only installs on systems with Python 3.11; the
vmImage ships Python 3.10. PyPI's libyang ships sdist only, so
pip has to build the CFFI extension — use --no-build-isolation
with apt's python3-cffi to sidestep a cffi version-mismatch
Exception that jammy's pip 22.0.2 build-isolation env triggers
(newer cffi in the overlay vs. the system /usr/lib/python3/
dist-packages/_cffi_backend.so that still wins on sys.path).
3.3.0 is the last 3.x release and includes patches we
upstreamed against 3.1.0.
* Drop the amd64/ubuntu-20.04 job, which has been pinned to
`condition: false` (i.e. never runs) for some time.
Signed-off-by: Brad House <brad@brad-house.com>
ZmqServer dispatches incoming messages on its poll thread by looking up
a ZmqMessageHandler pointer in a (db, table) map populated by
ZmqConsumerStateTable's constructor via registerMessageHandler() and
calling handler->handleReceivedData(). There was no symmetric
removeMessageHandler and no ZmqConsumerStateTable destructor — so when
a consumer went out of scope, the map kept the now-dangling pointer.
That bites in test code that declares its ZmqServer before its
ZmqConsumerStateTable (the natural order — server has to exist to be
passed by reference into the consumer's constructor). Reverse-order
destruction then runs the consumer's destructor first, which destroys
m_selectableEvent and closes the underlying eventfd, while the server's
mqPollThread is still running and may be partway through a dispatch
that ends in m_selectableEvent.notify(). write() on the closed fd
returns EBADF, SelectableEvent::notify() throws
runtime_error("write failed"), the exception escapes the poll thread,
and std::terminate aborts the process — visible in CI as a crash
attributed to whichever test happened to be RUNing next
(ZmqServerLazzyBind in practice, since gtest prints [ RUN ] before the
test body executes).
The fix moves the handler map and its mutex out of ZmqServer into a
small, separately-allocated ZmqHandlerRegistry class. The server and
every registered consumer co-own a std::shared_ptr<ZmqHandlerRegistry>,
so:
* The mutex is held across handler dispatch, so the consumer's
destructor (which calls removeHandler() on the registry) blocks
until any in-flight callback into it has returned — after which
its other members can safely destruct.
* The registry survives as long as either the server OR any
registered handler still holds a reference. Destruction order
between server and consumer no longer matters: whichever goes
away last leaves a live registry behind for the other's
destructor to use without touching freed memory.
The server's public surface — registerMessageHandler() and the new
removeMessageHandler() — is unchanged in signature; both delegate to
the registry. A new (internal) ZmqServer::getHandlerRegistry()
accessor returns the shared_ptr so ZmqMessageHandler implementations
can co-own the registry.
ZmqConsumerStateTable now caches its db name as std::string at
construction and stores std::shared_ptr<ZmqHandlerRegistry> instead of
ZmqServer&, so its destructor never dereferences the DBConnector or
the ZmqServer it was created with — only the shared registry.
Handler callbacks still must not themselves call register/removeHandler
on the registry (would self-deadlock); ZmqConsumerStateTable::
handleReceivedData only enqueues and notifies, so the restriction is
harmless in tree. Documented on the ZmqHandlerRegistry class.
Signed-off-by: Brad House <bhouse@nexthop.ai>
sonic-swss commit e6c482ca ("...") added -lnexthopgroup to fpmsyncd's
link line, expecting libnexthopgroup_*.deb to already be installed
when the swss build runs. sonic-swss-common's downstream "Compile
sonic swss" stage installs everything it needs from the common-lib
artifact, but its pattern list never picked up the new package, so
the link now fails with `cannot find -lnexthopgroup`. Add the
libnexthopgroup pattern next to the other Azure.sonic-buildimage.
common_libs entries in build-swss-template.yml so dpkg picks it up
in the existing install step.
Signed-off-by: Brad House <brad@brad-house.com>
ebfcc6b to
0ee673b
Compare
| if (m_rawhandlers.find(nlmsg_type) != m_rawhandlers.end()) | ||
| throw "Trying to register an already registered netlink message"; | ||
|
|
||
| m_rawhandlers[nlmsg_type] = callback; |
Check warning
Code scanning / CodeQL
Local variable address stored in non-local memory Warning
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 28 days ago
The safest fix without changing behavior is to enforce that only non-stack pointers can be registered, rejecting stack addresses at runtime before storing them in dispatcher maps. This keeps the existing non-owning raw-pointer API and callback semantics intact while preventing the specific dangling-pointer class flagged by CodeQL.
Best concrete change in common/netdispatcher.cpp:
- Add a small helper to detect likely stack addresses on Linux (compare pointer against current thread stack bounds via
pthread_getattr_np/pthread_attr_getstack). - In both
registerRawMessageHandlerandregisterMessageHandler, validatecallbackand throw if it points into stack memory. - Add needed standard/system includes in this file only.
This avoids changing headers, container types, or ownership model, and remains compatible with existing callers that pass heap/static handlers.
Suggested changeset
1
common/netdispatcher.cpp
| @@ -3,9 +3,39 @@ | ||
| #include "logger.h" | ||
|
|
||
| #include <map> | ||
| #include <stdexcept> | ||
| #include <pthread.h> | ||
| #include <cstdint> | ||
|
|
||
| using namespace swss; | ||
|
|
||
| namespace | ||
| { | ||
| bool isStackAddress(const void *ptr) | ||
| { | ||
| if (ptr == nullptr) | ||
| return false; | ||
|
|
||
| pthread_attr_t attr; | ||
| if (pthread_getattr_np(pthread_self(), &attr) != 0) | ||
| return false; | ||
|
|
||
| void *stackAddr = nullptr; | ||
| size_t stackSize = 0; | ||
| const int rc = pthread_attr_getstack(&attr, &stackAddr, &stackSize); | ||
| pthread_attr_destroy(&attr); | ||
|
|
||
| if (rc != 0 || stackAddr == nullptr || stackSize == 0) | ||
| return false; | ||
|
|
||
| const uintptr_t p = reinterpret_cast<uintptr_t>(ptr); | ||
| const uintptr_t start = reinterpret_cast<uintptr_t>(stackAddr); | ||
| const uintptr_t end = start + stackSize; | ||
|
|
||
| return p >= start && p < end; | ||
| } | ||
| } | ||
|
|
||
| #define MUTEX std::lock_guard<std::mutex> _lock(m_mutex); | ||
|
|
||
| NetDispatcher& NetDispatcher::getInstance() | ||
| @@ -22,6 +49,9 @@ | ||
| if (!callback) | ||
| throw "Trying to register a null callback"; | ||
|
|
||
| if (isStackAddress(callback)) | ||
| throw "Trying to register a callback with stack lifetime"; | ||
|
|
||
| if (m_handlers.find(nlmsg_type) != m_handlers.end()) | ||
| throw "Trying to register on already registered netlink message"; | ||
|
|
||
| @@ -35,6 +65,9 @@ | ||
| if (!callback) | ||
| throw "Trying to register a null callback"; | ||
|
|
||
| if (isStackAddress(callback)) | ||
| throw "Trying to register a callback with stack lifetime"; | ||
|
|
||
| if (m_rawhandlers.find(nlmsg_type) != m_rawhandlers.end()) | ||
| throw "Trying to register an already registered netlink message"; | ||
|
|
Copilot is powered by AI and may make mistakes. Always verify output.
sonic-swss-common: port to libyang3
…net#1188) Why The batched overloads of ZmqProducerStateTable::set/del/send that take a std::vector<KeyOpFieldsValuesTuple> are unreachable from the Go bindings today (and Python is in the same boat). SWIG happily generates the C trampolines and Go methods (e.g. SwigcptrZmqProducerStateTable.Set__SWIG_3), but the parameter type std::vector<KeyOpFieldsValuesTuple> is not %template'd and SWIG cannot synthesize a default constructor for the opaque underlying tuple element, so callers have no way to build the argument — the type exposes only Swigcptr(). Verified empirically in a clean trixie + SWIG 4.3 + Go 1.24 environment: Type %template? Constructor Add/Get/Size FieldValuePairs (vector<FieldValueTuple>) yes ✅ ✅ VectorString (vector<string>) yes ✅ ✅ KeyOpFieldsValuesQueue (deque<KeyOpFieldsValuesTuple>) yes ✅ ✅ vector<KeyOpFieldsValuesTuple> (parameter of batched set/send) no ❌ ❌ only Swigcptr() Adding a single %template is not enough: even with the list templated, the element std::tuple<…> itself has no usable constructor — std_vector.i does not synthesize constructors for opaque tuple elements (std_deque.i is more permissive, which is why the existing KeyOpFieldsValuesQueue works). So the cleanest fix is a small inline shim layer. Batched del(vector<string>) already works today because VectorString is templated. What Add three %inline helpers in pyext/swsscommon.i (also picked up by the goext build via the symlink): zmqProducerBatchedSet(p, keys, fvss) — all entries get op=SET zmqProducerBatchedDel(p, keys) — all entries get op=DEL zmqProducerBatchedSend(p, keys, ops, fvss) — caller supplies per-entry op for mixed batches Each helper takes parallel vectors of already-wrapped types (VectorString and FieldValuePairsList) and assembles the vector<KeyOpFieldsValuesTuple> on the C++ side before forwarding to the existing batched API. This mirrors the parallel-vector pattern Table::pops already uses. Size mismatches throw std::invalid_argument, which the existing SWIG exception bridge surfaces to callers as a recoverable panic. Why we want this now This unblocks bulk gNMI Set in sonic-gnmi (sonic-net/sonic-buildimage#27250 — bulk DASH route programming). Today MixedDbClient.handleTableData emits one ZMQ message per key; with these helpers it can ship N keys in a single message. Follow-up PR in sonic-gnmi to land afterwards.
Adds opt-in primitives to `swss::NotificationConsumer` for bounding queue growth and reducing cross-fanout cost on shared Redis pubsub channels. ## How I did it - **LRU-dedup queue policy** (`NotificationQueuePolicy::LruDedup`) — collapses byte-identical payloads on enqueue (`std::list` + `std::unordered_map<string, iter>`). Drain order: "last-seen time per unique payload." Memory bounded by `count(distinct in-flight payloads)`. - **5-arg `NotificationConsumer` constructor** takes the policy. The 4-arg constructor's mangled symbol is preserved verbatim (no ABI break for `python3-swsscommon`, etc.). - **`setOpAllowList(ops)`** — admission filter that drops messages whose JSON-array leading `op` is not in the set, before they consume queue memory. Defends against cross-fanout on shared channels like `"NOTIFICATIONS"`. Empty set (default) preserves legacy behavior. - **`setStatsLabel(label)`** — orch-qualified label so syslog can distinguish multiple consumers SUBSCRIBE'd to the same channel. - **Atomic stats counters** (`received`, `dropped_allowlist`, `pushed`, `dedup_hits`, `high_watermark`, `current_depth`) + `getStats()` + a self-throttled 5 s `SWSS_LOG_NOTICE` summary inline from `processReply` / `push`.
Added support for local ARS (Adaptive Routing and Switching). HLD: sonic-net/SONiC#1958 Signed-off-by: VladimirKuk <31180446+VladimirKuk@users.noreply.github.com>
0ee673b to
df62e71
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Raised PR for internal comments