Bläddra i källkod

packaging: add Dockerfiles, control templates, config, systemd, and maintainer scripts

- Dockerfile.base: Debian 13 (trixie) build image with all deps
- Dockerfile.build: multi-stage compile + package, outputs 4 .debs
- Control templates for: smartbotic-database, libsmartbotic-db-client,
  libsmartbotic-db-client-dev, smartbotic-db-cli
- Default production config.json with sane defaults
- smartbotic-database.service systemd unit
- server.postinst with migration from shadowman-database/callerai-storage
- lib.postinst/postrm with ldconfig triggers
fszontagh 3 månader sedan
förälder
incheckning
b0c6b10214

+ 37 - 0
packaging/Dockerfile.base

@@ -0,0 +1,37 @@
+# Smartbotic Database Build Base Image — Debian 13 (trixie)
+#
+# Build:
+#   docker buildx build -f packaging/Dockerfile.base -t smartbotic-db-build-base:debian13 .
+
+FROM debian:trixie
+
+ENV DEBIAN_FRONTEND=noninteractive
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+    build-essential \
+    cmake \
+    ninja-build \
+    git \
+    pkg-config \
+    ca-certificates \
+    ccache \
+    libssl-dev \
+    liblz4-dev \
+    protobuf-compiler \
+    libprotobuf-dev \
+    libgrpc++-dev \
+    protobuf-compiler-grpc \
+    nlohmann-json3-dev \
+    libspdlog-dev \
+    libfmt-dev \
+    dpkg-dev \
+    && rm -rf /var/lib/apt/lists/*
+
+ENV CCACHE_DIR=/ccache
+ENV CCACHE_MAXSIZE=2G
+ENV CCACHE_COMPRESS=1
+ENV CCACHE_COMPRESSLEVEL=6
+
+WORKDIR /build
+
+RUN echo "smartbotic-db-build-base:debian13:v1" > /etc/smartbotic-db-build-base

+ 75 - 0
packaging/Dockerfile.build

@@ -0,0 +1,75 @@
+# syntax=docker/dockerfile:1.4
+# Smartbotic Database Package Builder — Debian 13 (trixie)
+# Produces 4 .deb packages: server, libclient, libclient-dev, cli
+#
+# Usage:
+#   docker buildx build -f packaging/Dockerfile.build \
+#     --build-arg BASE_IMAGE=smartbotic-db-build-base:debian13 \
+#     --target packages --output "type=local,dest=dist/" .
+
+ARG BASE_IMAGE=debian:trixie
+FROM ${BASE_IMAGE} AS builder
+
+ARG BUILD_VERSION=0.0.0
+ARG BUILD_DEB_REVISION=1
+ARG BUILD_JOBS=16
+ARG BUILD_GIT_COMMIT=unknown
+ENV DEBIAN_FRONTEND=noninteractive
+ENV BUILD_VERSION=${BUILD_VERSION}
+ENV BUILD_DEB_REVISION=${BUILD_DEB_REVISION}
+ENV BUILD_JOBS=${BUILD_JOBS}
+
+ENV CCACHE_DIR=/ccache
+ENV CCACHE_MAXSIZE=2G
+ENV CCACHE_COMPRESS=1
+ENV CCACHE_COMPRESSLEVEL=6
+ENV PATH="/usr/lib/ccache:${PATH}"
+
+# Install deps if not using pre-built base
+RUN if [ ! -f /etc/smartbotic-db-build-base ]; then \
+    apt-get update && apt-get install -y --no-install-recommends \
+    build-essential cmake ninja-build git pkg-config ca-certificates ccache \
+    libssl-dev liblz4-dev \
+    protobuf-compiler libprotobuf-dev libgrpc++-dev protobuf-compiler-grpc \
+    nlohmann-json3-dev libspdlog-dev libfmt-dev dpkg-dev \
+    && rm -rf /var/lib/apt/lists/*; \
+    else echo "Using pre-built base: $(cat /etc/smartbotic-db-build-base)"; fi
+
+WORKDIR /build
+
+COPY CMakeLists.txt VERSION ./
+COPY cmake/ ./cmake/
+COPY proto/ ./proto/
+COPY client/ ./client/
+COPY service/ ./service/
+COPY cli/ ./cli/
+COPY tests/ ./tests/
+COPY packaging/ ./packaging/
+
+# Build with shared libs + Release
+RUN --mount=type=cache,target=/ccache,id=smartbotic-db-ccache \
+    cmake -B build -G Ninja \
+    -DCMAKE_BUILD_TYPE=Release \
+    -DCMAKE_C_COMPILER_LAUNCHER=ccache \
+    -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
+    -DSMARTBOTIC_DB_BUILD_SERVICE=ON \
+    -DSMARTBOTIC_DB_BUILD_CLIENT=ON \
+    -DSMARTBOTIC_DB_BUILD_CLI=ON \
+    -DSMARTBOTIC_DB_BUILD_TESTS=ON \
+    -DBUILD_SHARED_LIBS=ON \
+    && cmake --build build --parallel ${BUILD_JOBS} \
+    && ccache --show-stats || true
+
+# Run tests
+RUN cd build && LD_LIBRARY_PATH=./client:$LD_LIBRARY_PATH ./tests/test_vector_storage
+
+# Package
+FROM builder AS packager
+RUN mkdir -p /packages
+ENV OUTPUT_DIR=/packages
+RUN chmod +x /build/packaging/deb/create-debs.sh && \
+    /build/packaging/deb/create-debs.sh
+
+# Output
+FROM scratch AS packages
+COPY --from=packager /packages/*.deb /

+ 0 - 106
packaging/build.sh

@@ -1,106 +0,0 @@
-#!/bin/bash
-# Build smartbotic-database package
-
-set -e
-
-SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-ROOT_DIR="$(dirname "$SCRIPT_DIR")"
-
-# Read version from VERSION file
-VERSION=$(cat "$ROOT_DIR/VERSION" | tr -d '[:space:]')
-PLATFORM="debian13"
-
-# Parse arguments
-REBUILD_BASE=false
-CLEAR_CACHE=false
-NO_CACHE=false
-BUILD_VERSION=""
-
-while [[ $# -gt 0 ]]; do
-    case $1 in
-        --rebuild-base)
-            REBUILD_BASE=true
-            shift
-            ;;
-        --clear-cache)
-            CLEAR_CACHE=true
-            shift
-            ;;
-        --no-cache)
-            NO_CACHE=true
-            shift
-            ;;
-        *)
-            BUILD_VERSION="$1"
-            shift
-            ;;
-    esac
-done
-
-# Use provided version or default from VERSION file
-VERSION="${BUILD_VERSION:-$VERSION}"
-
-echo "Building smartbotic-database version $VERSION"
-
-# Create dist directory
-mkdir -p "$SCRIPT_DIR/dist"
-
-# Build using Docker if Dockerfile exists
-if [ -f "$SCRIPT_DIR/Dockerfile.build" ]; then
-    DOCKER_BUILD_ARGS=""
-
-    if [ "$NO_CACHE" = true ]; then
-        DOCKER_BUILD_ARGS="--no-cache"
-    fi
-
-    docker buildx build \
-        $DOCKER_BUILD_ARGS \
-        -f "$SCRIPT_DIR/Dockerfile.build" \
-        --build-arg BUILD_VERSION="$VERSION" \
-        --build-arg BUILD_GIT_COMMIT="$(git -C "$ROOT_DIR" rev-parse HEAD 2>/dev/null || echo 'unknown')" \
-        --build-arg BUILD_GIT_BRANCH="$(git -C "$ROOT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" \
-        --target packages \
-        --output "type=local,dest=$SCRIPT_DIR/dist/" \
-        "$ROOT_DIR"
-else
-    # Fall back to local build
-    echo "No Dockerfile.build found, building locally..."
-
-    BUILD_DIR="$ROOT_DIR/build"
-    PACKAGE_DIR="$SCRIPT_DIR/dist/smartbotic-database-$VERSION-$PLATFORM"
-
-    # Configure and build
-    cmake -B "$BUILD_DIR" -G Ninja \
-        -DCMAKE_BUILD_TYPE=Release \
-        -DSMARTBOTIC_DB_BUILD_SERVICE=ON \
-        -DSMARTBOTIC_DB_BUILD_CLIENT=ON \
-        "$ROOT_DIR"
-
-    ninja -C "$BUILD_DIR"
-
-    # Create package structure
-    rm -rf "$PACKAGE_DIR"
-    mkdir -p "$PACKAGE_DIR/bin"
-    mkdir -p "$PACKAGE_DIR/etc/systemd/system"
-
-    # Copy binary
-    cp "$BUILD_DIR/service/smartbotic-database" "$PACKAGE_DIR/bin/"
-
-    # Copy config
-    cp "$ROOT_DIR/service/config/database.json.example" "$PACKAGE_DIR/etc/smartbotic-database.json"
-
-    # Copy systemd unit
-    if [ -f "$SCRIPT_DIR/systemd/smartbotic-database.service" ]; then
-        cp "$SCRIPT_DIR/systemd/smartbotic-database.service" "$PACKAGE_DIR/etc/systemd/system/"
-    fi
-
-    # Create VERSION file
-    echo "$VERSION" > "$PACKAGE_DIR/VERSION"
-
-    # Create tarball
-    cd "$SCRIPT_DIR/dist"
-    tar -czf "smartbotic-database-$VERSION-$PLATFORM.tar.gz" "smartbotic-database-$VERSION-$PLATFORM"
-    rm -rf "smartbotic-database-$VERSION-$PLATFORM"
-
-    echo "Package created: $SCRIPT_DIR/dist/smartbotic-database-$VERSION-$PLATFORM.tar.gz"
-fi

+ 37 - 0
packaging/deb/config/config.json

@@ -0,0 +1,37 @@
+{
+  "log_level": "info",
+  "storage": {
+    "bind_address": "localhost",
+    "rpc_port": 9004,
+    "node_id": "smartbotic-db",
+    "data_directory": "/var/lib/smartbotic-database",
+    "memory": {
+      "max_memory_mb": 512,
+      "eviction_threshold_percent": 80,
+      "eviction_target_percent": 60,
+      "eviction_check_interval_ms": 5000
+    },
+    "persistence": {
+      "wal_sync_interval_ms": 100,
+      "snapshot_interval_sec": 3600,
+      "compression": "lz4"
+    },
+    "encryption": {
+      "enabled": true,
+      "key_file": "/var/lib/smartbotic-database/storage.key",
+      "auto_generate_key": true
+    },
+    "migrations": {
+      "enabled": false,
+      "directory": "/etc/smartbotic-database/migrations",
+      "auto_apply": false
+    },
+    "files": {
+      "max_file_size_mb": 500,
+      "cleanup_orphans_interval_sec": 3600
+    },
+    "replication": {
+      "enabled": false
+    }
+  }
+}

+ 4 - 0
packaging/deb/scripts/lib.postinst

@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+ldconfig
+exit 0

+ 4 - 0
packaging/deb/scripts/lib.postrm

@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+ldconfig
+exit 0

+ 67 - 0
packaging/deb/scripts/server.postinst

@@ -0,0 +1,67 @@
+#!/bin/bash
+# postinst for smartbotic-database (server)
+set -e
+
+CONFIG_FILE="/etc/smartbotic-database/config.json"
+DATA_DIR="/var/lib/smartbotic-database"
+
+case "$1" in
+    configure)
+        if ! getent group smartbotic-db >/dev/null 2>&1; then
+            addgroup --system smartbotic-db
+        fi
+        if ! getent passwd smartbotic-db >/dev/null 2>&1; then
+            adduser --system --ingroup smartbotic-db --home "$DATA_DIR" \
+                --shell /usr/sbin/nologin --gecos "Smartbotic Database Service" smartbotic-db
+        fi
+
+        install -d -o smartbotic-db -g smartbotic-db -m 0750 "$DATA_DIR"
+        install -d -o root -g smartbotic-db -m 0750 /etc/smartbotic-database
+
+        # ── Migration from shadowman-database ──
+        OLD_SM_DATA="/var/lib/shadowman/data/database"
+        OLD_SM_CONFIG="/etc/shadowman/database.json"
+        if [ -d "$OLD_SM_DATA" ] && [ "$(ls -A "$OLD_SM_DATA" 2>/dev/null)" ] && \
+           [ ! "$(ls -A "$DATA_DIR" 2>/dev/null)" ]; then
+            echo "smartbotic-database: migrating data from shadowman-database..."
+            cp -a "$OLD_SM_DATA"/. "$DATA_DIR"/
+            chown -R smartbotic-db:smartbotic-db "$DATA_DIR"
+        fi
+        if [ -f "$OLD_SM_CONFIG" ] && [ ! -f "$CONFIG_FILE" ]; then
+            cp "$OLD_SM_CONFIG" "$CONFIG_FILE"
+            sed -i 's|/var/lib/shadowman/data/database|/var/lib/smartbotic-database|g' "$CONFIG_FILE"
+            sed -i 's|/var/lib/shadowman/data/storage\.key|/var/lib/smartbotic-database/storage.key|g' "$CONFIG_FILE"
+        fi
+
+        # ── Migration from callerai-storage ──
+        OLD_CA_DATA="/var/lib/callerai/storage"
+        OLD_CA_CONFIG="/etc/callerai/storage.json"
+        if [ -d "$OLD_CA_DATA" ] && [ "$(ls -A "$OLD_CA_DATA" 2>/dev/null)" ] && \
+           [ ! "$(ls -A "$DATA_DIR" 2>/dev/null)" ]; then
+            echo "smartbotic-database: migrating data from callerai-storage..."
+            cp -a "$OLD_CA_DATA"/. "$DATA_DIR"/
+            chown -R smartbotic-db:smartbotic-db "$DATA_DIR"
+        fi
+        if [ -f "$OLD_CA_CONFIG" ] && [ ! -f "$CONFIG_FILE" ]; then
+            cp "$OLD_CA_CONFIG" "$CONFIG_FILE"
+            sed -i 's|/var/lib/callerai/storage|/var/lib/smartbotic-database|g' "$CONFIG_FILE"
+        fi
+
+        if [ -f "$CONFIG_FILE" ]; then
+            chown root:smartbotic-db "$CONFIG_FILE"
+            chmod 640 "$CONFIG_FILE"
+        fi
+
+        systemctl daemon-reload || true
+        if [ -z "$2" ]; then
+            systemctl enable smartbotic-database.service || true
+            systemctl start smartbotic-database.service || true
+        else
+            systemctl reset-failed smartbotic-database.service 2>/dev/null || true
+            systemctl restart smartbotic-database.service || true
+        fi
+        ;;
+    abort-upgrade|abort-remove|abort-deconfigure) ;;
+    *) echo "postinst called with unknown argument '$1'" >&2; exit 1 ;;
+esac
+exit 0

+ 14 - 0
packaging/deb/scripts/server.postrm

@@ -0,0 +1,14 @@
+#!/bin/bash
+set -e
+case "$1" in
+    remove) systemctl daemon-reload || true ;;
+    purge)
+        systemctl daemon-reload || true
+        rm -f /etc/smartbotic-database/config.json
+        rm -f /etc/smartbotic-database/config.json.dpkg-*
+        rmdir /etc/smartbotic-database 2>/dev/null || true
+        ;;
+    upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;;
+    *) echo "postrm called with unknown argument '$1'" >&2; exit 1 ;;
+esac
+exit 0

+ 12 - 0
packaging/deb/scripts/server.prerm

@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+case "$1" in
+    remove|deconfigure)
+        systemctl stop smartbotic-database.service || true
+        systemctl disable smartbotic-database.service || true
+        ;;
+    upgrade) systemctl stop smartbotic-database.service || true ;;
+    failed-upgrade) ;;
+    *) echo "prerm called with unknown argument '$1'" >&2; exit 1 ;;
+esac
+exit 0

+ 17 - 0
packaging/deb/systemd/smartbotic-database.service

@@ -0,0 +1,17 @@
+[Unit]
+Description=Smartbotic Database Service
+After=network.target
+
+[Service]
+Type=simple
+User=smartbotic-db
+Group=smartbotic-db
+ExecStart=/usr/bin/smartbotic-database --config /etc/smartbotic-database/config.json
+WorkingDirectory=/var/lib/smartbotic-database
+Restart=on-failure
+RestartSec=3
+TimeoutStopSec=30
+LimitNOFILE=65536
+
+[Install]
+WantedBy=multi-user.target

+ 13 - 0
packaging/deb/templates/control.cli

@@ -0,0 +1,13 @@
+Package: smartbotic-db-cli
+Version: {{VERSION}}
+Architecture: amd64
+Maintainer: Ferenc Szontagh <ferenc.szontagh@smartbotics.ai>
+Description: Smartbotic Database — CLI administration tool
+ Command-line tool for managing a smartbotic-database instance.
+ Connects via gRPC — does not require the server installed locally.
+Homepage: https://smartbotics.ai
+Section: contrib/utils
+Priority: optional
+License: proprietary
+Depends: libsmartbotic-db-client (>= {{VERSION}})
+Installed-Size: {{INSTALLED_SIZE}}

+ 13 - 0
packaging/deb/templates/control.dev

@@ -0,0 +1,13 @@
+Package: libsmartbotic-db-client-dev
+Version: {{VERSION}}
+Architecture: amd64
+Maintainer: Ferenc Szontagh <ferenc.szontagh@smartbotics.ai>
+Description: Smartbotic Database — client development files
+ C++ headers, linker symlink, proto source, and CMake config for
+ building applications against the smartbotic-database client API.
+Homepage: https://smartbotics.ai
+Section: contrib/libdevel
+Priority: optional
+License: proprietary
+Depends: libsmartbotic-db-client (= {{VERSION}}), libprotobuf-dev, libgrpc++-dev, libspdlog-dev, nlohmann-json3-dev
+Installed-Size: {{INSTALLED_SIZE}}

+ 13 - 0
packaging/deb/templates/control.lib

@@ -0,0 +1,13 @@
+Package: libsmartbotic-db-client
+Version: {{VERSION}}
+Architecture: amd64
+Maintainer: Ferenc Szontagh <ferenc.szontagh@smartbotics.ai>
+Description: Smartbotic Database — client shared library
+ Shared library for applications connecting to smartbotic-database
+ via gRPC. Includes compiled protobuf/gRPC stubs.
+Homepage: https://smartbotics.ai
+Section: contrib/libs
+Priority: optional
+License: proprietary
+Depends: libprotobuf32t64, libgrpc++1.51t64, libspdlog1.15, libfmt10
+Installed-Size: {{INSTALLED_SIZE}}

+ 18 - 0
packaging/deb/templates/control.server

@@ -0,0 +1,18 @@
+Package: smartbotic-database
+Version: {{VERSION}}
+Architecture: amd64
+Maintainer: Ferenc Szontagh <ferenc.szontagh@smartbotics.ai>
+Description: Smartbotic Database — document store with gRPC API
+ Standalone document database with gRPC API, vector similarity search,
+ WAL persistence, LZ4 compression, AES-256-GCM field-level encryption,
+ file storage with blob deduplication, and JSON-based migrations.
+ Proprietary software by SmartBotics Kft.
+Homepage: https://smartbotics.ai
+Section: contrib/utils
+Priority: optional
+License: proprietary
+Provides: shadowman-database, callerai-storage
+Conflicts: shadowman-database, callerai-storage
+Replaces: shadowman-database, callerai-storage
+Depends: libsmartbotic-db-client (= {{VERSION}}), libssl3t64, liblz4-1
+Installed-Size: {{INSTALLED_SIZE}}

+ 0 - 29
packaging/systemd/smartbotic-database.service

@@ -1,29 +0,0 @@
-[Unit]
-Description=Smartbotic Database Service
-Documentation=https://git.smartbotics.ai/fszontagh/smartbotic-database
-After=network.target
-
-[Service]
-Type=notify
-ExecStart=/opt/smartbotic/bin/smartbotic-database --config /etc/smartbotic/database.json
-Restart=on-failure
-RestartSec=5
-TimeoutStartSec=30
-WatchdogSec=60
-
-# Security hardening
-NoNewPrivileges=yes
-ProtectSystem=strict
-ProtectHome=read-only
-PrivateTmp=yes
-ReadWritePaths=/var/lib/smartbotic/database
-
-# Resource limits
-LimitNOFILE=65536
-LimitNPROC=4096
-
-# Environment
-Environment=LOG_LEVEL=info
-
-[Install]
-WantedBy=multi-user.target