Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
 
root / assets / solaris-11.svg
Author[]google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.c...> 2025-08-18 08:02 UTC
Committer[]Andy Green <andy@warmcat.com> 2025-08-22 14:35 UTC
Tree812e5d777bd28c151423f59969a52c282af53b3a   Raw Patch
 
feat: Add builder version reporting and remote rebuild
feat: Add builder version reporting and remote rebuild
diff --git a/assets/sai.css b/assets/sai.css index 5ba27f8..286761f 100644 --- a/assets/sai.css +++ b/assets/sai.css @@ -636,6 +636,9 @@ div.ibuil { color:#000000; padding:3px; border-radius:10px; + user-select: none; + -webkit-user-select: none; + cursor: pointer; } div.ibuilctr { @@ -830,3 +833,26 @@ img.branch { .activity-3 { animation: flash-fast 1s infinite; } + +.context-menu { + position: absolute; + background-color: #f9f9f9; + border: 1px solid #ccc; + padding: 5px; + z-index: 3000; +} + +.context-menu ul { + list-style: none; + padding: 0; + margin: 0; +} + +.context-menu li { + padding: 8px 12px; + cursor: pointer; +} + +.context-menu li:hover { + background-color: #f2f2f2; +} diff --git a/assets/sai.js b/assets/sai.js index 32167e0..734d886 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -880,6 +880,46 @@ function after_delete() { location.reload(); } +function createContextMenu(event, menuItems) { + event.preventDefault(); + + // Remove any existing context menu + const existingMenus = document.querySelectorAll(".context-menu"); + existingMenus.forEach(menu => { + document.body.removeChild(menu); + }); + + const menu = document.createElement("div"); + menu.className = "context-menu"; + menu.style.top = event.pageY + "px"; + menu.style.left = event.pageX + "px"; + + const ul = document.createElement("ul"); + menu.appendChild(ul); + + menuItems.forEach(item => { + const li = document.createElement("li"); + li.innerHTML = item.label; + if (item.callback) { + li.addEventListener("click", item.callback); + } + ul.appendChild(li); + }); + + document.body.appendChild(menu); + + const closeMenu = () => { + if (document.body.contains(menu)) { + document.body.removeChild(menu); + } + document.removeEventListener("click", closeMenu); + }; + + setTimeout(() => { + document.addEventListener("click", closeMenu); + }, 0); +} + function createBuilderDiv(plat) { const platDiv = document.createElement("div"); platDiv.className = "ibuil bdr"; @@ -916,6 +956,61 @@ function createBuilderDiv(plat) { innerHTML += `</div></td></tr></tbody></table>`; platDiv.innerHTML = innerHTML; + + const menuItems = [ + { label: `<b>SAI Hash:</b> ${plat.sai_hash}` }, + { label: `<b>LWS Hash:</b> ${plat.lws_hash}` }, + { + label: "Update SAI", + callback: () => { + const rebuildMsg = { + schema: "com.warmcat.sai.rebuild", + builder_name: plat.name + }; + sai.send(JSON.stringify(rebuildMsg)); + } + } + ]; + + platDiv.addEventListener("contextmenu", function(event) { + createContextMenu(event, menuItems); + }); + + let touchStartTime = 0; + let touchStartPos = { x: 0, y: 0 }; + + platDiv.addEventListener("touchstart", function(event) { + if (event.touches.length > 1) { + return; + } + touchStartTime = Date.now(); + const touch = event.touches[0]; + touchStartPos = { x: touch.pageX, y: touch.pageY }; + }); + + platDiv.addEventListener("touchend", function(event) { + const touchEndTime = Date.now(); + const touch = event.changedTouches[0]; + const touchEndPos = { x: touch.pageX, y: touch.pageY }; + const pressDuration = touchEndTime - touchStartTime; + const distance = Math.sqrt( + Math.pow(touchEndPos.x - touchStartPos.x, 2) + + Math.pow(touchEndPos.y - touchStartPos.y, 2) + ); + + if (pressDuration >= 500 && distance < 10) { + event.preventDefault(); + + const mockEvent = { + preventDefault: () => {}, + pageX: touchStartPos.x, + pageY: touchStartPos.y + }; + createContextMenu(mockEvent, menuItems); + } + touchStartTime = 0; + }); + return platDiv; } diff --git a/etc-sai-EXAMPLE/builder/conf b/etc-sai-EXAMPLE/builder/conf index aae370e..fd03488 100644 --- a/etc-sai-EXAMPLE/builder/conf +++ b/etc-sai-EXAMPLE/builder/conf @@ -2,6 +2,8 @@ "perms": "sai:nobody", "home": "/home/sai", "host": "bionic-noi", + "rebuild_script_user": "cd ~/libwebsockets/build && git fetch origin +main:m && git reset --hard m && make -j12 && cd ../../sai/build && git fetch origin +main:m && git reset --hard m && make -j12", + "rebuild_script_root": "cd /home/agreen/libwebsockets/build && make -j12 install && cd /home/agreen/sai/build && make -j12 install && systemctl restart sai-builder", # if you are using auto-power-on and off, the builder needs # to point to a sai-power instance that can coordinate power-off diff --git a/src/builder/CMakeLists.txt b/src/builder/CMakeLists.txt index 82eaff7..f1259ee 100644 --- a/src/builder/CMakeLists.txt +++ b/src/builder/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRCS b-logproxy.c b-refproxy.c b-load.c + ../common/c-utils.c ) set(requirements 1) diff --git a/src/builder/b-conf.c b/src/builder/b-conf.c index 49aae31..3d9bda7 100644 --- a/src/builder/b-conf.c +++ b/src/builder/b-conf.c @@ -41,7 +41,9 @@ static const char * const paths_global[] = { "power-on.url", "power-on.mac", "power-off.type", - "power-off.url" + "power-off.url", + "rebuild_script_user", + "rebuild_script_root" }; enum enum_paths_global { @@ -56,7 +58,9 @@ enum enum_paths_global { LEJPM_POWER_ON_URL, LEJPM_POWER_ON_MAC, LEJPM_POWER_OFF_TYPE, - LEJPM_POWER_OFF_URL + LEJPM_POWER_OFF_URL, + LEJPM_REBUILD_SCRIPT_USER, + LEJPM_REBUILD_SCRIPT_ROOT }; /* platform-related part */ @@ -111,6 +115,11 @@ saib_conf_cb(struct lejp_ctx *ctx, char reason) a->sai_plat->instances = 1; /* default */ + lws_strncpy(a->sai_plat->sai_hash, BUILD_INFO, + sizeof(a->sai_plat->sai_hash)); + lws_strncpy(a->sai_plat->lws_hash, LWS_BUILD_HASH, + sizeof(a->sai_plat->lws_hash)); + lws_dll2_add_tail(&a->sai_plat->sai_plat_list, &a->builder->sai_plat_owner); break; @@ -322,6 +331,14 @@ saib_conf_global_cb(struct lejp_ctx *ctx, char reason) pp = &a->builder->power_off_url; break; + case LEJPM_REBUILD_SCRIPT_USER: + pp = &a->builder->rebuild_script_user; + break; + + case LEJPM_REBUILD_SCRIPT_ROOT: + pp = &a->builder->rebuild_script_root; + break; + default: return 0; } diff --git a/src/builder/b-private.h b/src/builder/b-private.h index 67d0823..e9a71ec 100644 --- a/src/builder/b-private.h +++ b/src/builder/b-private.h @@ -120,6 +120,8 @@ struct sai_builder { const char *perms; /* user:group */ const char *host; /* prepended before hostname */ + const char *rebuild_script_user; + const char *rebuild_script_root; char path[256]; diff --git a/src/builder/b-sai.c b/src/builder/b-sai.c index 626afcd..a04e7ac 100644 --- a/src/builder/b-sai.c +++ b/src/builder/b-sai.c @@ -64,7 +64,7 @@ int getpid(void) { return 0; } static const char *config_dir = "/etc/sai/builder"; static int interrupted; static lws_state_notify_link_t nl; -static struct lws_spawn_piped *lsp_suspender; +struct lws_spawn_piped *lsp_suspender; struct sai_builder builder; @@ -741,8 +741,6 @@ int main(int argc, const char **argv) struct stat sb; const char *p; -#if !defined(WIN32) - if ((p = lws_cmdline_option(argc, argv, "-s"))) { ssize_t n = 0; @@ -772,6 +770,27 @@ int main(int argc, const char **argv) break; } +#if defined(WIN32) + /* + * On Windows, we can use the shutdown command. + * For suspend, we can use rundll32. + */ + switch(d) { + case 0: + system("shutdown /s /t 0"); + break; + case 1: + system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0"); + break; + case 3: + if (builder.rebuild_script_user && + builder.rebuild_script_root) { + if (system(builder.rebuild_script_user) == 0) + system(builder.rebuild_script_root); + } + break; + } +#else p = fork(); if (!p) switch(d) { @@ -785,16 +804,44 @@ int main(int argc, const char **argv) case 1: execl("/usr/bin/systemctl", "/usr/bin/systemctl", "suspend", NULL); break; + case 3: + if (builder.rebuild_script_user && + builder.rebuild_script_root) { + char cmd[8192]; + char user_buf[64]; + const char *user = "sai"; + int ret; + + if (builder.perms) { + lws_strncpy(user_buf, builder.perms, sizeof(user_buf)); + if (strchr(user_buf, ':')) + *strchr(user_buf, ':') = '\0'; + user = user_buf; + } + + lws_snprintf(cmd, sizeof(cmd), + "su - %s -c '%s'", + user, + builder.rebuild_script_user); + ret = system(cmd); + if (ret == 0) { + lws_snprintf(cmd, sizeof(cmd), + "PATH=/usr/local/bin:/usr/bin:/bin:/sbin:/usr/sbin %s", + builder.rebuild_script_root); + system(cmd); + } + } + break; } else waitpid(p, &status, 0); +#endif } lwsl_notice("%s: exiting suspend process\n", __func__); return 0; } -#endif if ((p = lws_cmdline_option(argc, argv, "-d"))) logs = atoi(p); diff --git a/src/builder/b-task.c b/src/builder/b-task.c index 85dd5f3..ea09f4e 100644 --- a/src/builder/b-task.c +++ b/src/builder/b-task.c @@ -42,14 +42,16 @@ const lws_struct_map_t lsm_schema_map_m_to_b[] = { LSM_SCHEMA (sai_cancel_t, NULL, lsm_task_cancel, "com.warmcat.sai.taskcan"), LSM_SCHEMA (sai_viewer_state_t, NULL, lsm_viewerstate_members, "com.warmcat.sai.viewerstate"), - LSM_SCHEMA (sai_resource_t, NULL, lsm_resource, "com-warmcat-sai-resource") + LSM_SCHEMA (sai_resource_t, NULL, lsm_resource, "com-warmcat-sai-resource"), + LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, "com.warmcat.sai.rebuild") }; enum { SAIB_RX_TASK_ALLOCATION, SAIB_RX_TASK_CANCEL, SAIB_RX_VIEWERSTATE, - SAIB_RX_RESOURCE_REPLY + SAIB_RX_RESOURCE_REPLY, + SAIB_RX_REBUILD }; static const char * const nsstates[] = { @@ -428,6 +430,8 @@ saib_sul_task_cancel(struct lws_sorted_usec_list *sul) saib_sul_task_cancel, 500 * LWS_US_PER_MS); } +extern struct lws_spawn_piped *lsp_suspender; + int saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len) { @@ -437,6 +441,7 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len) struct lejp_ctx ctx; lws_struct_args_t a; sai_cancel_t *can; + sai_rebuild_t *reb; char url[128], *p; sai_task_t *task; int n, m; @@ -819,6 +824,19 @@ saib_ws_json_rx_builder(struct sai_plat_server *spm, const void *in, size_t len) saib_handle_resource_result(spm, in, len); break; + case SAIB_RX_REBUILD: + reb = (sai_rebuild_t *)a.dest; + + lwsl_notice("%s: REBUILD: %s\n", __func__, reb->builder_name); + + if (lsp_suspender) { + uint8_t b = 3; + if (write(lws_spawn_get_fd_stdxxx(lsp_suspender, 0), &b, 1) != 1) + lwsl_err("%s: Failed to write to suspender\n", + __func__); + } + break; + default: break; } diff --git a/src/common/c-utils.c b/src/common/c-utils.c new file mode 100644 index 0000000..7d815fa --- /dev/null +++ b/src/common/c-utils.c @@ -0,0 +1,38 @@ +/* + * Sai common utils + * + * Copyright (C) 2025 Andy Green <andy@warmcat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation: + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include <libwebsockets.h> +#include "include/private.h" + +int +sai_uuid16_create(struct lws_context *context, char *dest33) +{ + uint8_t uuid[16]; + int n; + + if (lws_get_random(context, uuid, sizeof(uuid)) != sizeof(uuid)) + return -1; + + for (n = 0; n < 16; n++) + lws_snprintf(dest33 + (n * 2), 3, "%02X", uuid[n]); + + return 0; +} diff --git a/src/common/include/private.h b/src/common/include/private.h index 9ae4586..24d5325 100644 --- a/src/common/include/private.h +++ b/src/common/include/private.h @@ -221,6 +221,15 @@ typedef struct sai_cancel { char task_uuid[65]; } sai_cancel_t; +/* + * Browser is asking a builder to rebuild + */ + +typedef struct sai_rebuild { + lws_dll2_t list; + char builder_name[96]; +} sai_rebuild_t; + struct sai_event; @@ -405,6 +414,8 @@ typedef struct sai_plat { struct lws *wsi; /* server side only */ lws_dll2_owner_t env_head; + char sai_hash[41]; + char lws_hash[41]; uint64_t uid; lws_dll2_owner_t loads; int online; /* 1 = connected, 0 = offline */ @@ -474,10 +485,12 @@ extern const lws_struct_map_t lsm_schema_json_map_task[1], lsm_schema_json_map_event[1], lsm_resource[4], - lsm_power_state[3] + lsm_power_state[3], + lsm_rebuild[1], + lsm_schema_rebuild[1] ; -extern const lws_struct_map_t lsm_plat[6]; -extern const lws_struct_map_t lsm_plat_for_json[10]; +extern const lws_struct_map_t lsm_plat[8]; +extern const lws_struct_map_t lsm_plat_for_json[12]; extern const lws_ss_info_t ssi_said_logproxy; extern struct lws_ss_handle *ssh[3]; @@ -496,4 +509,6 @@ saicom_lp_callback_on_drain(saicom_drain_cb cb, void *opaque); void sul_idle_cb(lws_sorted_usec_list_t *sul); +int +sai_uuid16_create(struct lws_context *context, char *dest33); diff --git a/src/common/struct-metadata.c b/src/common/struct-metadata.c index 4899184..d13f3ec 100644 --- a/src/common/struct-metadata.c +++ b/src/common/struct-metadata.c @@ -47,6 +47,8 @@ const lws_struct_map_t lsm_plat[] = { /* !!! keep extern length in common/includ LSM_STRING_PTR (sai_plat_t, platform, "platform"), LSM_UNSIGNED (sai_plat_t, last_seen, "last_seen"), LSM_CARRAY (sai_plat_t, peer_ip, "peer_ip"), + LSM_CARRAY (sai_plat_t, sai_hash, "sai_hash"), + LSM_CARRAY (sai_plat_t, lws_hash, "lws_hash"), }; // This is the map for serializing to JSON @@ -61,6 +63,8 @@ const lws_struct_map_t lsm_plat_for_json[] = { LSM_SIGNED(sai_plat_t, powering_up, "powering_up"), LSM_SIGNED(sai_plat_t, powering_down, "powering_down"), LSM_CARRAY(sai_plat_t, peer_ip, "peer_ip"), + LSM_CARRAY(sai_plat_t, sai_hash, "sai_hash"), + LSM_CARRAY(sai_plat_t, lws_hash, "lws_hash"), }; const lws_struct_map_t lsm_schema_map_plat_simple[] = { @@ -163,6 +167,15 @@ const lws_struct_map_t lsm_task_cancel[] = { LSM_CARRAY (sai_cancel_t, task_uuid, "task_uuid"), }; +const lws_struct_map_t lsm_rebuild[] = { + LSM_CARRAY (sai_rebuild_t, builder_name, "builder_name"), +}; + +const lws_struct_map_t lsm_schema_rebuild[] = { + LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, + "com.warmcat.sai.rebuild") +}; + const lws_struct_map_t lsm_schema_json_map_can[] = { LSM_SCHEMA (sai_cancel_t, NULL, lsm_task_cancel, "com.warmcat.sai.taskcan") diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 2e29af7..9b5eaba 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRCS s-central.c s-websrv.c s-resource.c + ../common/c-utils.c ) set(requirements 1) diff --git a/src/server/s-comms.c b/src/server/s-comms.c index 5b669ab..6dc669d 100644 --- a/src/server/s-comms.c +++ b/src/server/s-comms.c @@ -70,12 +70,6 @@ extern const lws_ss_info_t ssi_server; */ int -sai_uuid16_create(struct lws_context *context, char *dest33) -{ - return lws_hex_random(context, dest33, 33); -} - -int sai_sqlite3_statement(sqlite3 *pdb, const char *cmd, const char *desc) { sqlite3_stmt *sm; diff --git a/src/server/s-private.h b/src/server/s-private.h index 5850bab..4b3366b 100644 --- a/src/server/s-private.h +++ b/src/server/s-private.h @@ -105,6 +105,7 @@ struct pss { lws_dll2_owner_t platform_owner; /* sai_platform_t builder offers */ lws_dll2_owner_t task_cancel_owner; /* sai_platform_t builder offers */ + lws_dll2_owner_t rebuild_owner; lws_dll2_owner_t aft_owner; /* for statefully spooling artifact info */ lws_dll2_owner_t res_owner; /* sai_resource_requisition_t * owner of resource objects related @@ -240,9 +241,6 @@ int sai_sqlite3_statement(sqlite3 *pdb, const char *cmd, const char *desc); int -sai_uuid16_create(struct lws_context *context, char *dest33); - -int sais_event_db_ensure_open(struct vhd *vhd, const char *event_uuid, char can_create, sqlite3 **ppdb); void diff --git a/src/server/s-websrv.c b/src/server/s-websrv.c index d67086a..f12c519 100644 --- a/src/server/s-websrv.c +++ b/src/server/s-websrv.c @@ -69,6 +69,8 @@ static const lws_struct_map_t lsm_schema_json_map[] = { "com.warmcat.sai.taskcan"), LSM_SCHEMA (sai_viewer_state_t, NULL, lsm_viewercount_members, "com.warmcat.sai.viewercount"), + LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, + "com.warmcat.sai.rebuild"), }; enum { @@ -77,6 +79,7 @@ enum { SAIS_WS_WEBSRV_RX_EVENTDELETE, SAIS_WS_WEBSRV_RX_TASKCANCEL, SAIS_WS_WEBSRV_RX_VIEWERCOUNT, + SAIS_WS_WEBSRV_RX_REBUILD, }; void @@ -117,6 +120,28 @@ reject: return 1; } +static int +sais_validate_builder_name(const char *id) +{ + const char *idin = id; + + while (*id) { + if (!((*id >= '0' && *id <= '9') || + (*id >= 'a' && *id <= 'z') || + (*id >= 'A' && *id <= 'Z') || + *id == '.' || *id == '/' || *id == '-' || *id == '_')) + goto reject; + id++; + } + + return 0; +reject: + + lwsl_notice("%s: Invalid builder name '%s'\n", __func__, idin); + + return 1; +} + int sais_websrv_queue_tx(struct lws_ss_handle *h, void *buf, size_t len) { @@ -567,6 +592,41 @@ websrvss_ws_rx(void *userobj, const uint8_t *buf, size_t len, int flags) } break; } + case SAIS_WS_WEBSRV_RX_REBUILD: + { + sai_rebuild_t *reb = (sai_rebuild_t *)a.dest; + sai_plat_t *cb; + + if (sais_validate_builder_name(reb->builder_name)) + goto soft_error; + + cb = sais_builder_from_uuid(m->vhd, reb->builder_name, + __FILE__, __LINE__); + if (!cb) { + lwsl_info("%s: unknown builder %s for rebuild\n", + __func__, reb->builder_name); + lwsac_free(&a.ac); + break; + } + + /* cb->wsi is the builder connection */ + lws_start_foreach_dll(struct lws_dll2 *, p, + m->vhd->builders.head) { + struct pss *pss = lws_container_of(p, struct pss, same); + + if (pss->wsi == cb->wsi) { + sai_rebuild_t *r = malloc(sizeof(*r)); + if (!r) + break; + *r = *reb; + lws_dll2_add_tail(&r->list, + &pss->rebuild_owner); + lws_callback_on_writable(pss->wsi); + break; + } + } lws_end_foreach_dll(p); + } + break; } return 0; diff --git a/src/server/s-ws-builder.c b/src/server/s-ws-builder.c index 43d23db..73b07fd 100644 --- a/src/server/s-ws-builder.c +++ b/src/server/s-ws-builder.c @@ -566,6 +566,10 @@ handle: live_cb->wsi = pss->wsi; live_cb->ongoing = 0; /* Reset ongoing task count on connect */ lws_strncpy(live_cb->peer_ip, pss->peer_ip, sizeof(live_cb->peer_ip)); + lws_strncpy(live_cb->sai_hash, build->sai_hash, + sizeof(live_cb->sai_hash)); + lws_strncpy(live_cb->lws_hash, build->lws_hash, + sizeof(live_cb->lws_hash)); live_cb->online = 1; } else { /* New builder, create a deep-copied, malloc'd object */ @@ -583,6 +587,10 @@ handle: live_cb->platform = p_str + nlen; memcpy(p_str + nlen, build->platform, plen); live_cb->instances = build->instances; + lws_strncpy(live_cb->sai_hash, build->sai_hash, + sizeof(live_cb->sai_hash)); + lws_strncpy(live_cb->lws_hash, build->lws_hash, + sizeof(live_cb->lws_hash)); live_cb->wsi = pss->wsi; live_cb->online = 1; lws_strncpy(live_cb->peer_ip, pss->peer_ip, sizeof(live_cb->peer_ip)); @@ -629,6 +637,8 @@ handle: * callback_on_writable handler to empty it */ + sais_list_builders(vhd); + break; bail: @@ -1077,6 +1087,27 @@ sais_ws_json_tx_builder(struct vhd *vhd, struct pss *pss, uint8_t *buf, goto send_json; } + if (pss->rebuild_owner.head) { + /* + * Pending rebuild message to send + */ + sai_rebuild_t *r = lws_container_of(pss->rebuild_owner.head, + sai_rebuild_t, list); + + js = lws_struct_json_serialize_create(lsm_schema_rebuild, + LWS_ARRAY_SIZE(lsm_schema_rebuild), 0, r); + if (!js) + return 1; + + n = (int)lws_struct_json_serialize(js, p, lws_ptr_diff_size_t(end, p), &w); + lws_struct_json_serialize_destroy(&js); + + lws_dll2_remove(&r->list); + free(r); + + goto send_json; + } + if (pss->task_cancel_owner.head) { /* * Pending cancel message to send diff --git a/src/web/w-comms.c b/src/web/w-comms.c index fd6b06b..8ce280f 100644 --- a/src/web/w-comms.c +++ b/src/web/w-comms.c @@ -130,12 +130,6 @@ saiw_update_viewer_count(struct vhd *vhd) */ int -sai_uuid16_create(struct lws_context *context, char *dest33) -{ - return lws_hex_random(context, dest33, 33); -} - -int sai_sqlite3_statement(sqlite3 *pdb, const char *cmd, const char *desc) { sqlite3_stmt *sm; diff --git a/src/web/w-private.h b/src/web/w-private.h index 0e06094..2cbc1c7 100644 --- a/src/web/w-private.h +++ b/src/web/w-private.h @@ -251,9 +251,6 @@ int sai_sqlite3_statement(sqlite3 *pdb, const char *cmd, const char *desc); int -sai_uuid16_create(struct lws_context *context, char *dest33); - -int sais_event_db_ensure_open(struct vhd *vhd, const char *event_uuid, char can_create, sqlite3 **ppdb); void diff --git a/src/web/w-ws-browser.c b/src/web/w-ws-browser.c index e67fb6f..955a22d 100644 --- a/src/web/w-ws-browser.c +++ b/src/web/w-ws-browser.c @@ -97,6 +97,8 @@ static const lws_struct_map_t lsm_schema_json_map_bwsrx[] = { "com.warmcat.sai.taskcan"), LSM_SCHEMA (sai_load_report_t, NULL, lsm_load_report_members, "com.warmcat.sai.loadreport"), + LSM_SCHEMA (sai_rebuild_t, NULL, lsm_rebuild, + "com.warmcat.sai.rebuild"), }; enum { @@ -107,6 +109,7 @@ enum { SAIM_WS_BROWSER_RX_EVENTDELETE, SAIM_WS_BROWSER_RX_TASKCANCEL, SAIM_WS_BROWSER_RX_JS_HELLO, + SAIM_WS_BROWSER_RX_REBUILD, }; @@ -569,6 +572,17 @@ saiw_ws_json_rx_browser(struct vhd *vhd, struct pss *pss, uint8_t *buf, saiw_task_cancel(vhd, can->task_uuid); break; + case SAIM_WS_BROWSER_RX_REBUILD: + if (!sais_conn_auth(pss)) + goto soft_error; + + /* + * User is asking us to rebuild a builder + */ + + saiw_websrv_queue_tx(vhd->h_ss_websrv, buf, bl); + break; + default: assert(0); break;
Page fetched 0s ago, creation time: 44ms (vhost etag hits: 0%, cache hits: 0%)