Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/pack_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ jobs:
mkdir build
cd build
export BUNDLE_REPO_TYPE=${{ needs.pack.outputs.target == 'release' && 'release_candidate' || 'dev' }}
cmake -DPACK=1 -DPACK_BUNDLE=1 ..
cmake -DPACK=1 -DPACK_BUNDLE=1 -DWITH_UI=1 ..
cmake --build . --target package
cache_key: pack_${{ matrix.DISTR }}_${{ matrix.arch }}
artifact_list: "build/manticore*deb"
Expand Down Expand Up @@ -232,7 +232,7 @@ jobs:
mkdir build
cd build
export BUNDLE_REPO_TYPE=${{ needs.pack.outputs.target == 'release' && 'release_candidate' || 'dev' }}
cmake -DPACK=1 -DPACK_BUNDLE=1 ..
cmake -DPACK=1 -DPACK_BUNDLE=1 -DWITH_UI=1 ..
cmake --build . --target package
cache_key: pack_${{ matrix.DISTR }}_${{ matrix.arch }}
artifact_list: "build/manticore*rpm"
Expand All @@ -258,7 +258,7 @@ jobs:
mkdir build
cd build
export BUNDLE_REPO_TYPE=${{ needs.pack.outputs.target == 'release' && 'release_candidate' || 'dev' }}
cmake -DPACK=1 -DPACK_BUNDLE=1 -DDL_CURL=1 \
cmake -DPACK=1 -DPACK_BUNDLE=1 -DWITH_UI=1 -DDL_CURL=1 \
-DCURL_LIBRARY=${HOMEBREW_PREFIX}/opt/curl/lib/libcurl.dylib \
-DCURL_LIBRARY_RELEASE=${HOMEBREW_PREFIX}/opt/curl/lib/libcurl.dylib ..
cmake --build . --target package
Expand All @@ -282,7 +282,7 @@ jobs:
mkdir build
cd build
export BUNDLE_REPO_TYPE=${{ needs.pack.outputs.target == 'release' && 'release_candidate' || 'dev' }}
cmake -DPACK=1 -DPACK_BUNDLE=1 ..
cmake -DPACK=1 -DPACK_BUNDLE=1 -DWITH_UI=1 ..
cmake --build . --target package
cache_key: pack_windows_x64
artifact_list: "build/manticore*exe build/manticore*zip"
Expand Down
21 changes: 11 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -660,16 +660,17 @@ foreach (var BINDIR SBINDIR LIBEXECDIR SYSCONFDIR SHAREDSTATEDIR LOCALSTATEDIR R
cmake_print_variables ( CMAKE_INSTALL_${var} CMAKE_INSTALL_FULL_${var} )
endforeach ()

# Configure CPack source packaging for SRPM generation
set ( CPACK_SOURCE_GENERATOR "RPM" )
set ( CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}" )

# For source RPMs: Override the make command to use cmake --build instead
# This automatically handles any generator (Unix Makefiles, Ninja, etc.)
if (CPACK_SOURCE_GENERATOR STREQUAL "RPM" OR CPACK_RPM_PACKAGE_SOURCES)
set ( CPACK_RPM_SPEC_MORE_DEFINE "${CPACK_RPM_SPEC_MORE_DEFINE}
%global __make cmake --build . --parallel")
endif()
# Configure CPack source packaging only when SRPM generation was explicitly requested.
# Local binary builds should not depend on CPack source templates being available.
if ( BUILD_SRPMS OR CPACK_RPM_PACKAGE_SOURCES )
set ( CPACK_SOURCE_GENERATOR "RPM" )
set ( CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}" )

# For source RPMs: override the make command to use cmake --build instead.
# This automatically handles any generator (Unix Makefiles, Ninja, etc.)
set ( CPACK_RPM_SPEC_MORE_DEFINE "${CPACK_RPM_SPEC_MORE_DEFINE}
%global __make cmake --build . --parallel" )
endif ()

# Configure source directories for debuginfo packages
# This is required when debuginfo packaging is enabled
Expand Down
6 changes: 3 additions & 3 deletions cmake/external-build.cmake.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ if (NOT DEVMODE)
SOURCE_DIR @MODULE_SRC@
@CMAKE_ARGS@
BUILD_COMMAND "@CMAKE_COMMAND@" -E echo "Starting build config RelWithDebInfo"
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=RelWithDebInfo .
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_OSX_ARCHITECTURES=@CMAKE_SYSTEM_PROCESSOR@ .
COMMAND "@CMAKE_COMMAND@" --build . --config RelWithDebInfo
COMMAND "@CMAKE_COMMAND@" --install . --config RelWithDebInfo --prefix "@MODULE_BUILD@"
COMMAND "@CMAKE_COMMAND@" -E echo "Starting build config Debug"
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=Debug .
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_OSX_ARCHITECTURES=@CMAKE_SYSTEM_PROCESSOR@ .
COMMAND "@CMAKE_COMMAND@" --build . --config Debug --clean-first
COMMAND "@CMAKE_COMMAND@" --install . --config Debug --prefix "@MODULE_BUILD@"
INSTALL_COMMAND ""
Expand All @@ -33,7 +33,7 @@ else ()
SOURCE_DIR @MODULE_SRC@
@CMAKE_ARGS@
BUILD_COMMAND "@CMAKE_COMMAND@" -E echo "Starting build config ${BUILD_TYPE}"
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=${BUILD_TYPE} .
COMMAND "@CMAKE_COMMAND@" -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_OSX_ARCHITECTURES=@CMAKE_SYSTEM_PROCESSOR@ .
COMMAND "@CMAKE_COMMAND@" --build . --config ${BUILD_TYPE}
COMMAND "@CMAKE_COMMAND@" --install . --config ${BUILD_TYPE} --prefix "@MODULE_BUILD@"
INSTALL_COMMAND ""
Expand Down
2 changes: 1 addition & 1 deletion misc/ctest/gltest.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ if (WITH_COVERAGE)
set (WITH_POSTGRESQL "$ENV{WITH_POSTGRESQL}" )
endif()
# common test options
set ( CONFIG_OPTIONS "WITH_ODBC=1;WITH_RE2=1;WITH_STEMMER=1;WITH_POSTGRESQL=${WITH_POSTGRESQL};WITH_EXPAT=1;WITH_SSL=1" )
set ( CONFIG_OPTIONS "WITH_ODBC=1;WITH_RE2=1;WITH_STEMMER=1;WITH_POSTGRESQL=${WITH_POSTGRESQL};WITH_EXPAT=1;WITH_SSL=1;WITH_UI=1" )
if ( PACK )
LIST ( APPEND CONFIG_OPTIONS "PACK=1" )
endif ()
Expand Down
8 changes: 7 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ if (WITH_STEMMER)
target_link_libraries ( lmanticore PRIVATE stemmer::stemmer )
endif ()
if (WITH_RE2)
# Prefer the headers that belong to the imported re2::re2 archive.
# Homebrew's generic include path may also contain re2 headers with a newer ABI,
# which breaks the link when we intentionally use the cached static library.
target_include_directories ( lmanticore BEFORE PRIVATE
$<TARGET_PROPERTY:re2::re2,INTERFACE_INCLUDE_DIRECTORIES> )
target_link_libraries ( lmanticore PRIVATE re2::re2 )
endif ()

Expand Down Expand Up @@ -283,10 +288,11 @@ trace ( lextra )
trace ( lsearchd )

add_subdirectory ( daemon )
add_subdirectory ( ui )

# our executables
add_executable ( searchd searchd.cpp )
target_link_libraries ( searchd daemon searchd_ssl lmanticore lsearchd )
target_link_libraries ( searchd daemon searchd_ssl lmanticore lsearchd lui )

if (NOT STATIC_BINARY)
add_executable ( indexer indexer.cpp )
Expand Down
4 changes: 3 additions & 1 deletion src/gtests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@ target_link_libraries ( gmanticoretest PRIVATE
GTest::gmock_main
lmanticore
lsearchd
lui
searchd_ssl
source_svpipe
daemon
lui
)

if (WITH_EXPAT)
Expand All @@ -55,4 +57,4 @@ endif ()

if (QFUZZER)
target_link_libraries ( gmanticoretest PRIVATE -fsanitize=address )
endif()
endif()
17 changes: 17 additions & 0 deletions src/searchd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
#include "taskflushmutable.h"
#include "taskpreread.h"
#include "searchdbuddy.h"
#include "ui/searchdui.h"
#include "detail/indexlink.h"
#include "detail/expmeter.h"

Expand Down Expand Up @@ -14084,6 +14085,9 @@ void ConfigureSearchd ( const CSphConfig & hConf, bool bOptPIDFile, bool bTestMo
if ( hSearchd("seamless_rotate") )
g_bSeamlessRotate = ( hSearchd["seamless_rotate"].intval()!=0 );

if ( hSearchd("ui") )
g_bUI = ( hSearchd["ui"].intval()!=0 );

if ( hSearchd ( "grouping_in_utc" ) )
{
if ( IsTimeZoneSet() )
Expand Down Expand Up @@ -15491,6 +15495,19 @@ int WINAPI ServiceMain ( int argc, char **argv ) EXCLUDES (MainThread)

g_bJsonConfigLoadedOk = true;

if ( g_bUI )
{
for ( const auto & tDesc : dListenerDescs )
{
if ( tDesc.m_eProto == Proto_e::HTTP || tDesc.m_eProto == Proto_e::HTTPS )
{
const char * sAddr = tDesc.m_sAddr.IsEmpty() ? "localhost" : tDesc.m_sAddr.cstr();
sphInfo ( "Web UI available at http://%s:%d/ui/", sAddr, tDesc.m_iPort );
break;
}
}
}

dListenerDescs.Reset(); // make valgrind happy

// ready, steady, go
Expand Down
1 change: 1 addition & 0 deletions src/searchdaemon.h
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,7 @@ enum class EHTTP_ENDPOINT : BYTE
CLI,
CLI_JSON,
ES_BULK,
UI,

TOTAL
};
Expand Down
25 changes: 24 additions & 1 deletion src/searchdhttp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "client_session.h"
#include "tracer.h"
#include "searchdbuddy.h"
#include "ui/searchdui.h"
#include "compressed_http.h"
#include "daemon/logger.h"
#include "daemon/search_handler.h"
Expand Down Expand Up @@ -170,14 +171,18 @@ static Endpoint_t g_dEndpoints[(size_t)EHTTP_ENDPOINT::TOTAL] =
{ "pq", "json/pq" },
{ "cli", nullptr },
{ "cli_json", nullptr },
{ "_bulk", nullptr }
{ "_bulk", nullptr },
{ "ui", nullptr }
};

EHTTP_ENDPOINT StrToHttpEndpoint ( const CSphString& sEndpoint ) noexcept
{
if ( sEndpoint.Begins ( g_dEndpoints[(int)EHTTP_ENDPOINT::PQ].m_szName1 ) || sEndpoint.Begins ( g_dEndpoints[(int)EHTTP_ENDPOINT::PQ].m_szName2 ) )
return EHTTP_ENDPOINT::PQ;

if ( sEndpoint.Begins ( g_dEndpoints[(int)EHTTP_ENDPOINT::UI].m_szName1 ) )
return EHTTP_ENDPOINT::UI;

for ( int i = 0; i < (int)EHTTP_ENDPOINT::TOTAL; ++i )
if ( sEndpoint == g_dEndpoints[i].m_szName1 || ( g_dEndpoints[i].m_szName2 && sEndpoint == g_dEndpoints[i].m_szName2 ) )
return EHTTP_ENDPOINT ( i );
Expand Down Expand Up @@ -878,6 +883,16 @@ R"index(<!DOCTYPE html>

static void HttpHandlerIndexPage ( CSphVector<BYTE> & dData )
{
// If UI is enabled, redirect root to /ui/
if ( g_bUI )
{
CSphString sHttp;
sHttp.SetSprintf ( "HTTP/1.1 302 Found\r\nLocation: /ui/\r\nContent-Length: 0\r\n\r\n" );
dData.Resize ( sHttp.Length() );
memcpy ( dData.Begin(), sHttp.cstr(), sHttp.Length() );
return;
}

StringBuilder_c sIndexPage;
sIndexPage.Appendf ( g_sIndexPage, g_sStatusVersion.cstr() );

Expand Down Expand Up @@ -2474,6 +2489,14 @@ HttpProcessResult_t ProcessHttpQuery ( CharStream_c & tSource, Str_t & sSrcQuery
const CSphString & sEndpoint = hOptions["endpoint"];
tRes.m_eEndpoint = StrToHttpEndpoint ( sEndpoint );

// Try to serve embedded UI assets
if ( HttpServeUI ( sEndpoint, dResult, eRequestType == HTTP_HEAD ) )
{
tRes.m_eReplyHttpCode = EHTTP_STATUS::_200;
tRes.m_bOk = true;
return tRes;
}

std::unique_ptr<HttpHandler_c> pHandler = CreateHttpHandler ( tRes.m_eEndpoint, tSource, sSrcQuery, hOptions, eRequestType );
if ( !pHandler )
{
Expand Down
1 change: 1 addition & 0 deletions src/sphinxutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,7 @@ static KeyDesc_t g_dKeysSearchd[] =
{ "preopen_tables", 0, nullptr },
{ "buddy_path", 0, nullptr },
{ "telemetry", 0, nullptr },
{ "ui", 0, nullptr },
{ "auto_schema", 0, nullptr },
{ "engine", 0, nullptr },
{ "join_cache_size", 0, nullptr },
Expand Down
45 changes: 45 additions & 0 deletions src/ui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
option ( WITH_UI "Build embedded web UI" OFF )

if ( WITH_UI )
find_program ( NODE_EXECUTABLE node )
find_program ( NPM_EXECUTABLE npm )
find_program ( UI_PYTHON_EXECUTABLE python3 )
if ( NOT NODE_EXECUTABLE OR NOT NPM_EXECUTABLE )
message ( FATAL_ERROR "WITH_UI=ON requires node and npm" )
elseif ( NOT UI_PYTHON_EXECUTABLE )
message ( FATAL_ERROR "WITH_UI=ON requires python3" )
endif ()
endif ()

set ( UI_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/app" )
set ( UI_DIST_DIR "${UI_APP_DIR}/dist" )
set ( UI_GENERATED "${CMAKE_CURRENT_BINARY_DIR}/ui_assets_generated.cpp" )

if ( WITH_UI )
add_custom_command (
OUTPUT "${UI_DIST_DIR}/index.html"
COMMAND ${NPM_EXECUTABLE} install
COMMAND ${NPM_EXECUTABLE} run build
WORKING_DIRECTORY "${UI_APP_DIR}"
COMMENT "Building Svelte UI"
)

add_custom_command (
OUTPUT "${UI_GENERATED}"
COMMAND ${UI_PYTHON_EXECUTABLE}
"${CMAKE_CURRENT_SOURCE_DIR}/embed_assets.py"
"${UI_DIST_DIR}"
"${UI_GENERATED}"
DEPENDS "${UI_DIST_DIR}/index.html"
COMMENT "Embedding UI assets into C++ source"
)

add_library ( lui OBJECT searchdui.cpp "${UI_GENERATED}" )
target_compile_definitions ( lui PRIVATE WITH_UI=1 )
else ()
add_library ( lui OBJECT searchdui.cpp )
target_compile_definitions ( lui PRIVATE WITH_UI=0 )
endif ()

target_include_directories ( lui PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" )
target_link_libraries ( lui PRIVATE lextra generated_config )
2 changes: 2 additions & 0 deletions src/ui/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
dist/
13 changes: 13 additions & 0 deletions src/ui/app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Manticore Search</title>
<link rel="icon" type="image/svg+xml" href="/ui/favicon.svg" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Loading
Loading