mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-29 20:23:01 +02:00
Compare commits
3
Commits
v25.08.2
...
upload-image
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc0edaf59c | ||
|
|
60b3a97f0e | ||
|
|
e534c0bd2d |
@@ -1,5 +1,11 @@
|
|||||||
# /telemetry/optics is for streaming (not used atm)
|
# /telemetry/optics is for streaming (not used atm)
|
||||||
|
# Proxy buffer settings for large files
|
||||||
|
proxy_buffering off; # Disable buffering for streaming
|
||||||
|
proxy_request_buffering off; # Stream request body immediately
|
||||||
|
proxy_max_temp_file_size 0; # No temp files
|
||||||
location ~ ^/(restconf|yang|.well-known)/ {
|
location ~ ^/(restconf|yang|.well-known)/ {
|
||||||
|
client_max_body_size 200M;
|
||||||
|
client_body_buffer_size 1M;
|
||||||
grpc_pass grpc://[::1]:10080;
|
grpc_pass grpc://[::1]:10080;
|
||||||
grpc_set_header Host $host;
|
grpc_set_header Host $host;
|
||||||
grpc_set_header X-Real-IP $remote_addr;
|
grpc_set_header X-Real-IP $remote_addr;
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ PKG_CHECK_MODULES([jansson], [jansson >= 2.0.0])
|
|||||||
PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
|
PKG_CHECK_MODULES([libite], [libite >= 2.6.1])
|
||||||
PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36])
|
PKG_CHECK_MODULES([sysrepo], [sysrepo >= 2.2.36])
|
||||||
PKG_CHECK_MODULES([libsrx], [libsrx >= 1.0.0])
|
PKG_CHECK_MODULES([libsrx], [libsrx >= 1.0.0])
|
||||||
|
PKG_CHECK_MODULES([libssl], [libssl >= 1.0.0])
|
||||||
|
|
||||||
# Control build with automake flags
|
# Control build with automake flags
|
||||||
AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"])
|
AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"])
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ confd_plugin_la_CFLAGS = \
|
|||||||
$(libite_CFLAGS) \
|
$(libite_CFLAGS) \
|
||||||
$(sysrepo_CFLAGS) \
|
$(sysrepo_CFLAGS) \
|
||||||
$(libsrx_CFLAGS) \
|
$(libsrx_CFLAGS) \
|
||||||
|
$(libssl_CFLAGS) \
|
||||||
$(CFLAGS)
|
$(CFLAGS)
|
||||||
|
|
||||||
confd_plugin_la_LIBADD = \
|
confd_plugin_la_LIBADD = \
|
||||||
@@ -20,7 +21,8 @@ confd_plugin_la_LIBADD = \
|
|||||||
$(jansson_LIBS) \
|
$(jansson_LIBS) \
|
||||||
$(libite_LIBS) \
|
$(libite_LIBS) \
|
||||||
$(sysrepo_LIBS) \
|
$(sysrepo_LIBS) \
|
||||||
$(libsrx_LIBS)
|
$(libsrx_LIBS) \
|
||||||
|
$(libssl_LIBS)
|
||||||
|
|
||||||
confd_plugin_la_SOURCES = \
|
confd_plugin_la_SOURCES = \
|
||||||
base64.c base64.h \
|
base64.c base64.h \
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
/* SPDX-License-Identifier: BSD-3-Clause */
|
/* SPDX-License-Identifier: BSD-3-Clause */
|
||||||
#include <srx/common.h>
|
#include <srx/common.h>
|
||||||
#include <srx/lyx.h>
|
#include <srx/lyx.h>
|
||||||
|
#include <openssl/bio.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "rauc-installer.h"
|
#include "rauc-installer.h"
|
||||||
@@ -21,24 +24,111 @@ static RaucInstaller *infix_system_sw_new_rauc(void)
|
|||||||
return rauc;
|
return rauc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int base64_decode_inplace(char *input, size_t input_len, size_t *output_len)
|
||||||
|
{
|
||||||
|
BIO *bio, *b64;
|
||||||
|
int decode_len;
|
||||||
|
|
||||||
|
bio = BIO_new_mem_buf(input, input_len);
|
||||||
|
if (!bio) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
b64 = BIO_new(BIO_f_base64());
|
||||||
|
if (!b64) {
|
||||||
|
BIO_free(bio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||||
|
bio = BIO_push(b64, bio);
|
||||||
|
|
||||||
|
/* Decode directly into the same buffer */
|
||||||
|
decode_len = BIO_read(bio, input, input_len);
|
||||||
|
BIO_free_all(bio);
|
||||||
|
|
||||||
|
if (decode_len < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*output_len = decode_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
||||||
const char *path, const sr_val_t *input,
|
const char *path, const sr_val_t *input,
|
||||||
const size_t input_cnt, sr_event_t event,
|
const size_t input_cnt, sr_event_t event,
|
||||||
unsigned request_id, sr_val_t **output,
|
unsigned request_id, sr_val_t **output,
|
||||||
size_t *output_cnt, void *priv)
|
size_t *output_cnt, void *priv)
|
||||||
{
|
{
|
||||||
char *url = input->data.string_val;
|
|
||||||
sr_error_t srerr = SR_ERR_OK;
|
sr_error_t srerr = SR_ERR_OK;
|
||||||
GError *raucerr = NULL;
|
GError *raucerr = NULL;
|
||||||
RaucInstaller *rauc;
|
RaucInstaller *rauc = NULL;
|
||||||
|
char *install_source = NULL;
|
||||||
|
|
||||||
DEBUG("url:%s", url);
|
const char *url = NULL;
|
||||||
|
char *binary_data = NULL;
|
||||||
|
size_t binary_len = 0;
|
||||||
|
size_t decoded_len = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < input_cnt; i++) {
|
||||||
|
if (strcmp(input[i].xpath, "/infix-system:install-bundle/url") == 0) {
|
||||||
|
if (input[i].type == SR_STRING_T) {
|
||||||
|
url = input[i].data.string_val;
|
||||||
|
}
|
||||||
|
} else if (strcmp(input[i].xpath, "/infix-system:install-bundle/image") == 0) {
|
||||||
|
if (input[i].type == SR_BINARY_T) {
|
||||||
|
binary_data = (char *)input[i].data.binary_val; // Cast away const for in-place decode
|
||||||
|
binary_len = strlen(binary_data); // Length of base64 string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (url) {
|
||||||
|
DEBUG("Installing from URL: %s", url);
|
||||||
|
install_source = (char *)url;
|
||||||
|
|
||||||
|
} else if (binary_data) {
|
||||||
|
const char *temp_dir = "/tmp";
|
||||||
|
char path[256];
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
DEBUG("Installing from uploaded binary data (%zu bytes base64)", binary_len);
|
||||||
|
|
||||||
|
if (base64_decode_inplace(binary_data, binary_len, &decoded_len) != 0) {
|
||||||
|
sr_session_set_netconf_error(session, "application", "invalid-value",
|
||||||
|
NULL, NULL, "Failed to decode base64 image data", 0);
|
||||||
|
srerr = SR_ERR_INVAL_ARG;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmkpath(0775, "%s/images", temp_dir);
|
||||||
|
snprintf(path, sizeof(path), "%s/images/install_bundle", temp_dir);
|
||||||
|
|
||||||
|
fp = fopen(path, "wb");
|
||||||
|
if (!fp) {
|
||||||
|
ERROR("Could not open %s", path);
|
||||||
|
return SR_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(binary_data, sizeof(char), decoded_len, fp);
|
||||||
|
fclose(fp);
|
||||||
|
install_source = path;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ERROR("Unknown source");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
rauc = infix_system_sw_new_rauc();
|
rauc = infix_system_sw_new_rauc();
|
||||||
if (!rauc)
|
if (!rauc) {
|
||||||
return SR_ERR_INTERNAL;
|
sr_session_set_netconf_error(session, "application", "operation-failed",
|
||||||
|
NULL, NULL, "Failed to initialize RAUC installer", 0);
|
||||||
|
srerr = SR_ERR_INTERNAL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
rauc_installer_call_install_sync(rauc, url, NULL, &raucerr);
|
rauc_installer_call_install_sync(rauc, install_source, NULL, &raucerr);
|
||||||
if (raucerr) {
|
if (raucerr) {
|
||||||
sr_session_set_netconf_error(session, "application", "operation-failed",
|
sr_session_set_netconf_error(session, "application", "operation-failed",
|
||||||
NULL, NULL, raucerr->message, 0);
|
NULL, NULL, raucerr->message, 0);
|
||||||
@@ -46,13 +136,18 @@ static int infix_system_sw_install(sr_session_ctx_t *session, uint32_t sub_id,
|
|||||||
srerr = SR_ERR_OPERATION_FAILED;
|
srerr = SR_ERR_OPERATION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref(rauc);
|
cleanup:
|
||||||
|
if (rauc) {
|
||||||
|
g_object_unref(rauc);
|
||||||
|
}
|
||||||
|
|
||||||
return srerr;
|
return srerr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
boot order can only be: primary, secondary and net, limited by model
|
boot order can only be: primary, secondary and net, limited by model
|
||||||
*/
|
*/
|
||||||
static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t sub_id,
|
static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t sub_id,
|
||||||
const char *path, const sr_val_t *input,
|
const char *path, const sr_val_t *input,
|
||||||
const size_t input_cnt, sr_event_t event,
|
const size_t input_cnt, sr_event_t event,
|
||||||
@@ -63,24 +158,24 @@ static int infix_system_sw_set_boot_order(sr_session_ctx_t *session, uint32_t su
|
|||||||
const sr_val_t *val = &input[i];
|
const sr_val_t *val = &input[i];
|
||||||
|
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
strlcat(boot_order, " ", sizeof(boot_order));
|
strlcat(boot_order, " ", sizeof(boot_order));
|
||||||
strlcat(boot_order, val->data.string_val, sizeof(boot_order));
|
strlcat(boot_order, val->data.string_val, sizeof(boot_order));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fexist("/sys/firmware/devicetree/base/chosen/u-boot,version")) {
|
if (fexist("/sys/firmware/devicetree/base/chosen/u-boot,version")) {
|
||||||
if (systemf("fw_setenv BOOT_ORDER %s", boot_order)) {
|
if (systemf("fw_setenv BOOT_ORDER %s", boot_order)) {
|
||||||
ERROR("Set-boot-order: Failed to set boot order in U-Boot");
|
ERROR("Set-boot-order: Failed to set boot order in U-Boot");
|
||||||
return SR_ERR_INTERNAL;
|
return SR_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
} else if (fexist("/mnt/aux/grub/grubenv")) {
|
} else if (fexist("/mnt/aux/grub/grubenv")) {
|
||||||
if (systemf("grub-editenv /mnt/aux/grub/grubenv set ORDER=\"%s\"", boot_order)) {
|
if (systemf("grub-editenv /mnt/aux/grub/grubenv set ORDER=\"%s\"", boot_order)) {
|
||||||
ERROR("Set-boot-order: Failed to set boot order in Grub");
|
ERROR("Set-boot-order: Failed to set boot order in Grub");
|
||||||
return SR_ERR_INTERNAL;
|
return SR_ERR_INTERNAL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ERROR("No supported boot loader found");
|
ERROR("No supported boot loader found");
|
||||||
return SR_ERR_UNSUPPORTED;
|
return SR_ERR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return SR_ERR_OK;
|
return SR_ERR_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,16 +204,42 @@ submodule infix-system-software {
|
|||||||
description
|
description
|
||||||
"Upgrade the system's software by installing the specified bundle.";
|
"Upgrade the system's software by installing the specified bundle.";
|
||||||
input {
|
input {
|
||||||
leaf url {
|
choice source {
|
||||||
type string;
|
|
||||||
mandatory true;
|
mandatory true;
|
||||||
description
|
description
|
||||||
"The location of the software bundle, specified as a Uniform
|
"Source of the software bundle to install.";
|
||||||
Resource Locator (URL). Currently supported protocols include
|
case url {
|
||||||
FTP, HTTP(S) and SCP.";
|
leaf url {
|
||||||
|
type string;
|
||||||
|
description
|
||||||
|
"The location of the software bundle, specified as a Uniform
|
||||||
|
Resource Locator (URL). Currently supported protocols include
|
||||||
|
FTP, HTTP(S) and SCP.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case upload {
|
||||||
|
leaf image {
|
||||||
|
type binary;
|
||||||
|
description
|
||||||
|
"The image data to install, provided as base64-encoded binary data.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rpc install-upload-bundle {
|
||||||
|
nacm:default-deny-all;
|
||||||
|
description "Upgrade the system's software by installing from a supplied blob.";
|
||||||
|
input {
|
||||||
|
leaf image {
|
||||||
|
type binary;
|
||||||
|
mandatory true;
|
||||||
|
description "The image to install";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rpc set-boot-order {
|
rpc set-boot-order {
|
||||||
nacm:default-deny-all;
|
nacm:default-deny-all;
|
||||||
description
|
description
|
||||||
|
|||||||
Reference in New Issue
Block a user