-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
np2 sr setup NEW library for setup.sh
... installing all the required SR modules. Useful for cross-compilation.
- Loading branch information
1 parent
c1a8e0e
commit 39bf57d
Showing
5 changed files
with
370 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
if(NOT NP2SRV_VERSION) | ||
message(FATAL_ERROR "Please use the root CMakeLists file instead.") | ||
endif() | ||
|
||
project(np2_sr_setup C) | ||
|
||
# source files | ||
set(LIB_SRC | ||
np2_sr_setup.c) | ||
|
||
# generate YANG header files | ||
add_custom_command(OUTPUT np2_sr_yang.h | ||
COMMAND ${CMAKE_COMMAND} -E env | ||
NP2_MODULE_DIR=${CMAKE_CURRENT_SOURCE_DIR}/../modules | ||
LN2_MODULE_DIR=${LN2_YANG_MODULE_DIR} | ||
NP2_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR} | ||
${CMAKE_CURRENT_SOURCE_DIR}/generate.sh | ||
COMMENT "Generating YANG header files (generate.sh)..." | ||
) | ||
|
||
include_directories(${CMAKE_CURRENT_BINARY_DIR}) | ||
|
||
# lib target | ||
add_library(np2_sr_setup ${LIB_SRC} np2_sr_yang.h) | ||
|
||
# reuse server variables | ||
target_link_libraries(np2_sr_setup ${LIBYANG_LIBRARIES}) | ||
target_link_libraries(np2_sr_setup ${SYSREPO_LIBRARIES}) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
#!/usr/bin/env bash | ||
|
||
if [ -z "$NP2_MODULE_DIR" -o -z "$LN2_MODULE_DIR" -o -z "$NP2_BINARY_DIR" ]; then | ||
echo "Required environment variables not defined!" | ||
exit 1 | ||
fi | ||
|
||
|
||
# start the YANG array | ||
MAIN_YANG_ARRAY=" | ||
struct { | ||
const char *file; | ||
const char *data; | ||
int len; | ||
} yang_files[] = { | ||
" | ||
|
||
# generate headers from all the YANG modules | ||
NP2_MODDIR=${DESTDIR}${NP2_MODULE_DIR} | ||
LN2_MODDIR=${DESTDIR}${LN2_MODULE_DIR} | ||
BINDIR=${DESTDIR}${NP2_BINARY_DIR} | ||
for YANG_PATH in ${NP2_MODDIR}/*.yang ${LN2_MODDIR}/*.yang; do | ||
# get module name | ||
YANG_FILE="$(basename "${YANG_PATH}")" | ||
|
||
if [[ "$MAIN_YANG_ARRAY" =~ "\"$YANG_FILE\"" ]]; then | ||
# duplicate module | ||
continue | ||
fi | ||
|
||
# generate HEX | ||
HEX=$(echo "$(cat "${YANG_PATH}")" | xxd -i -c1) | ||
LENGTH=$((${#HEX}/8)) | ||
|
||
# generate array name | ||
ARRAY_NAME="$(echo "${YANG_FILE}" | tr -- "-@." "_")" | ||
|
||
# generate header file name without the revision | ||
HEADER_FILE="${ARRAY_NAME}.h" | ||
|
||
# print into a C header file | ||
echo -e "const char ${ARRAY_NAME}[] = {\n$HEX\n};\nconst int ${ARRAY_NAME}_l = ${LENGTH};" > "${BINDIR}/${HEADER_FILE}" | ||
|
||
# build all the include lines in the main header | ||
MAIN_INCLUDE_LINES="${MAIN_INCLUDE_LINES}#include \"${HEADER_FILE}\"\n" | ||
|
||
# build the array of modules | ||
MAIN_YANG_ARRAY="${MAIN_YANG_ARRAY} {.file = \"${YANG_FILE}\", .data = ${ARRAY_NAME}, .len = ${ARRAY_NAME}_l},\n" | ||
done | ||
|
||
# end the YANG array | ||
MAIN_YANG_ARRAY="${MAIN_YANG_ARRAY} {.file = NULL, .data = NULL}\n};\n\n" | ||
|
||
|
||
# import module arrays | ||
cur_dir=$(dirname "$0") | ||
source "${cur_dir}/../scripts/common.sh" | ||
|
||
# start install and feature arrays | ||
MAIN_FEATURE_ARRAY="const char **yang_features[] = {\n" | ||
MAIN_INSTALL_ARRAY="const char *yang_install[] = {\n" | ||
COUNT=0 | ||
|
||
# generate install and features arrays | ||
for LINE in "${NP2_MODULES[@]}" "${LN2_MODULES[@]}"; do | ||
((COUNT+=1)) | ||
|
||
# get file and array name | ||
FILE="$(echo "$LINE" | sed 's/\([^ ]*\).*/\1/')" | ||
ARRAY_NAME="$(echo "${FILE}" | tr -- "-@." "_")_f" | ||
|
||
# generate feature array | ||
HAS_FEATURES=$(echo "$LINE" | grep " -e ") | ||
if [ -z "$HAS_FEATURES" ]; then | ||
FEATURES="NULL" | ||
else | ||
FEATURES="${ARRAY_NAME}" | ||
MOD_FEATURES="const char *${ARRAY_NAME}[] = {" | ||
LINE=$(echo "$LINE" | sed 's/[^ ]* \(.*\)/\1/') | ||
while [ "${LINE:0:3}" = "-e " ]; do | ||
# skip "-e " | ||
LINE=${LINE:3} | ||
# parse feature | ||
FEATURE=$(echo "$LINE" | sed 's/\([^ ]*\).*/\1/') | ||
|
||
MOD_FEATURES="$MOD_FEATURES\"$FEATURE\", " | ||
|
||
# next iteration, skip this feature | ||
LINE=$(echo "$LINE" | sed 's/[^ ]* \(.*\)/\1/') | ||
done | ||
MOD_FEATURES="${MOD_FEATURES}NULL}" | ||
|
||
MAIN_FEATURE_MODS="${MAIN_FEATURE_MODS}${MOD_FEATURES};\n" | ||
fi | ||
|
||
MAIN_FEATURE_ARRAY="${MAIN_FEATURE_ARRAY} ${FEATURES},\n" | ||
MAIN_INSTALL_ARRAY="${MAIN_INSTALL_ARRAY} \"${FILE}\",\n" | ||
done | ||
|
||
# end install and feature array | ||
MAIN_FEATURE_ARRAY="${MAIN_FEATURE_ARRAY}};\n\n" | ||
MAIN_INSTALL_ARRAY="${MAIN_INSTALL_ARRAY}};\n" | ||
|
||
MAIN_INSTALL_COUNT="int yang_install_count = ${COUNT};" | ||
|
||
# generate the main header | ||
echo -e "#include <stdlib.h>\n\n${MAIN_INCLUDE_LINES}\ | ||
${MAIN_YANG_ARRAY}\ | ||
${MAIN_FEATURE_MODS}\ | ||
${MAIN_FEATURE_ARRAY}\ | ||
${MAIN_INSTALL_ARRAY}\ | ||
${MAIN_INSTALL_COUNT}" > "${BINDIR}/np2_sr_yang.h" |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
/** | ||
* @file np2_sr_setup.c | ||
* @author Michal Vasko <[email protected]> | ||
* @brief netopeer2-server sysrepo YANG module setup library | ||
* | ||
* @copyright | ||
* Copyright (c) 2024 Deutsche Telekom AG. | ||
* Copyright (c) 2024 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. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
#define _GNU_SOURCE | ||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <sys/stat.h> | ||
#include <unistd.h> | ||
|
||
#include <libyang/libyang.h> | ||
#include <sysrepo.h> | ||
|
||
#include "np2_sr_yang.h" | ||
|
||
#define ERR(msg, ...) fprintf(stderr, msg "\n", __VA_ARGS__) | ||
#define ERRMSG(msg) fprintf(stderr, msg "\n") | ||
|
||
/** | ||
* @brief Check a module in the specific revision and all the features is not already installed. | ||
* | ||
* @param[in] file YANG module file name. | ||
* @param[in] features Array of enabled features. | ||
* @param[in] conn Sysrepo connection to use. | ||
* @param[out] processed Whether the module needs tobe installed or was processed. | ||
* @return 0 on success. | ||
* @return non-zero on error. | ||
*/ | ||
static int | ||
np2_sr_setup_mod_check(const char *file, const char **features, sr_conn_ctx_t *conn, int *processed) | ||
{ | ||
int rc = 0, i, r; | ||
const struct ly_ctx *ctx = sr_acquire_context(conn); | ||
const struct lys_module *mod; | ||
const char *ptr; | ||
char *name = NULL, *revision = NULL; | ||
LY_ERR lyrc; | ||
|
||
*processed = 0; | ||
|
||
/* parse name and revision */ | ||
ptr = strchr(file, '@'); | ||
name = strndup(file, ptr - file); | ||
++ptr; | ||
revision = strndup(ptr, strlen(ptr) - 5); | ||
if (!name || !revision) { | ||
ERRMSG("Failed to allocate memory."); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
/* check the file is installed */ | ||
mod = ly_ctx_get_module_implemented(ctx, name); | ||
if (!mod) { | ||
goto cleanup; | ||
} | ||
if (!revision || strcmp(mod->revision, revision)) { | ||
/* different revision, will fail during installation */ | ||
goto cleanup; | ||
} | ||
|
||
/* we will adjust enabled features */ | ||
*processed = 1; | ||
|
||
if (!features) { | ||
goto cleanup; | ||
} | ||
|
||
/* check/enable all the features */ | ||
for (i = 0; features[i]; ++i) { | ||
lyrc = lys_feature_value(mod, features[i]); | ||
if (lyrc == LY_ENOTFOUND) { | ||
ERR("Failed to find feature \"%s\" in \"%s\".", features[i], name); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
if (lyrc == LY_ENOT) { | ||
/* enable feature, context will be changed */ | ||
sr_release_context(conn); | ||
r = sr_enable_module_feature(conn, name, features[i]); | ||
ctx = sr_acquire_context(conn); | ||
|
||
if (r) { | ||
ERR("Failed to enable feature \"%s\" in \"%s\".", features[i], name); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
mod = ly_ctx_get_module_implemented(ctx, name); | ||
} | ||
} | ||
|
||
cleanup: | ||
sr_release_context(conn); | ||
free(name); | ||
free(revision); | ||
return rc; | ||
} | ||
|
||
int | ||
np2_sr_setup(const char *owner, const char *group, mode_t perm) | ||
{ | ||
int rc = 0, fd, r, i, mod_count; | ||
sr_conn_ctx_t *conn = NULL; | ||
sr_install_mod_t *mods = NULL; | ||
|
||
/* log */ | ||
sr_log_stderr(SR_LL_WRN); | ||
|
||
/* connect */ | ||
if (sr_connect(0, &conn)) { | ||
ERRMSG("Failed to connect to sysrepo."); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
/* print all the modules into files */ | ||
for (i = 0; yang_files[i].file; ++i) { | ||
fd = open(yang_files[i].file, O_WRONLY | O_CREAT | O_TRUNC, 00600); | ||
if (fd < 0) { | ||
ERR("Failed to create \"%s\".", yang_files[i].file); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
r = write(fd, yang_files[i].data, yang_files[i].len); | ||
close(fd); | ||
|
||
if (r != yang_files[i].len) { | ||
ERR("Failed to write \"%s\".", yang_files[i].file); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
} | ||
|
||
/* prepare modules to install */ | ||
mods = calloc(yang_install_count, sizeof *mods); | ||
if (!mods) { | ||
ERRMSG("Failed to allocate memory."); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
mod_count = 0; | ||
for (i = 0; i < yang_install_count; ++i) { | ||
/* first check that the module is not installed already and all its features enabled */ | ||
if (np2_sr_setup_mod_check(yang_install[i], yang_features[i], conn, &r)) { | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
if (r) { | ||
continue; | ||
} | ||
|
||
mods[mod_count].schema_path = yang_install[i]; | ||
mods[mod_count].features = yang_features[i]; | ||
mods[mod_count].owner = owner; | ||
mods[mod_count].group = group; | ||
mods[mod_count].perm = perm; | ||
|
||
++mod_count; | ||
} | ||
|
||
/* install modules */ | ||
if (sr_install_modules2(conn, mods, mod_count, ".", NULL, NULL, 0)) { | ||
ERRMSG("Failed to install modules."); | ||
rc = 1; | ||
goto cleanup; | ||
} | ||
|
||
cleanup: | ||
free(mods); | ||
sr_disconnect(conn); | ||
for (i = 0; yang_files[i].file; ++i) { | ||
unlink(yang_files[i].file); | ||
} | ||
return rc; | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/** | ||
* @file np2_sr_setup.h | ||
* @author Michal Vasko <[email protected]> | ||
* @brief netopeer2-server sysrepo YANG module setup library header | ||
* | ||
* @copyright | ||
* Copyright (c) 2024 Deutsche Telekom AG. | ||
* Copyright (c) 2024 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. | ||
* You may obtain a copy of the License at | ||
* | ||
* https://opensource.org/licenses/BSD-3-Clause | ||
*/ | ||
|
||
#ifndef NP2_SR_SETUP_H_ | ||
#define NP2_SR_SETUP_H_ | ||
|
||
#include <sys/stat.h> | ||
|
||
/** | ||
* @brief Install all YANG modules required by netopeer2-server into sysrepo. | ||
* | ||
* Logs to stderr. | ||
* | ||
* @param[in] owner Optional owner of the installed modules, process user by default. | ||
* @param[in] group Optional group of the installed modules, process group or configured sysrepo group by default. | ||
* @param[in] perm Optional specific permissions of the installed modules. | ||
* @return 0 on success. | ||
* @return non-zero on error. | ||
*/ | ||
int np2_sr_setup(const char *owner, const char *group, mode_t perm); | ||
|
||
#endif /* NP2_SR_SETUP_H_ */ |