Bläddra i källkod

build(packaging): pin the db client the server deb is built against

vectorapi links libsmartbotic-db-client.so.2, and every 2.x client shares that
SONAME, so a deb compiled against a newer client installs cleanly next to an
older one on the target and only segfaults on the next service restart. The
build now compiles against DB_CLIENT_VERSION (default 2.11.1-1, what prod has
installed and held).

Publishing a client re-indexes the apt pool, so the pinned version is usually
no longer installable from the repo - installing it by version failed outright.
build.sh therefore vendors the matching .debs from DEB_REPO_DIR/dist into
packaging/vendor/ (gitignored) and the image installs those, falling back to
the apt pin when they are absent. The base image prints the client version it
resolved, so the build log records what the binary was linked against.
fszontagh 1 vecka sedan
förälder
incheckning
80265a8a3f
4 ändrade filer med 42 tillägg och 4 borttagningar
  1. 4 0
      .gitignore
  2. 14 4
      packaging/Dockerfile.base
  3. 24 0
      packaging/build.sh
  4. 0 0
      packaging/vendor/.gitkeep

+ 4 - 0
.gitignore

@@ -15,3 +15,7 @@ compile_commands.json
 
 # Playwright MCP session artifacts (browser snapshots/console logs)
 .playwright-mcp/
+
+# Client debs vendored into the Docker build when the pinned version has
+# dropped out of the apt repo index (build.sh populates this).
+packaging/vendor/*.deb

+ 14 - 4
packaging/Dockerfile.base

@@ -29,6 +29,11 @@ RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
 # version installed on the deploy target; when the target's DB moves, bump this
 # and ship both together.
 ARG DB_CLIENT_VERSION=2.11.1-1
+
+# Publishing a new client re-indexes the apt pool, so the pinned version is
+# often no longer installable from the repo. build.sh copies the matching .debs
+# here from DEB_REPO_DIR when it finds them; an empty dir falls back to apt.
+COPY packaging/vendor/ /tmp/db-client-vendor/
 RUN curl -fsSL https://repository.smartbotics.ai/smartbotics-repo.gpg \
         | gpg --dearmor -o /usr/share/keyrings/smartbotics-repo.gpg \
     && printf 'machine repository.smartbotics.ai\nlogin %s\npassword %s\n' "$REPO_USER" "$REPO_PASS" \
@@ -37,7 +42,12 @@ RUN curl -fsSL https://repository.smartbotics.ai/smartbotics-repo.gpg \
     && echo "deb [signed-by=/usr/share/keyrings/smartbotics-repo.gpg] https://repository.smartbotics.ai trixie main" \
         > /etc/apt/sources.list.d/smartbotics.list \
     && apt-get update \
-    && apt-get install -y --no-install-recommends \
-        "libsmartbotic-db-client-dev=${DB_CLIENT_VERSION}" \
-        "libsmartbotic-db-client=${DB_CLIENT_VERSION}" \
-    && rm -rf /var/lib/apt/lists/*
+    && if ls /tmp/db-client-vendor/*.deb >/dev/null 2>&1; then \
+           apt-get install -y --no-install-recommends /tmp/db-client-vendor/*.deb; \
+       else \
+           apt-get install -y --no-install-recommends \
+               "libsmartbotic-db-client-dev=${DB_CLIENT_VERSION}" \
+               "libsmartbotic-db-client=${DB_CLIENT_VERSION}"; \
+       fi \
+    && dpkg-query -W -f='pinned client: ${Package} ${Version}\n' libsmartbotic-db-client \
+    && rm -rf /var/lib/apt/lists/* /tmp/db-client-vendor

+ 24 - 0
packaging/build.sh

@@ -18,6 +18,10 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
 PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
 
 BASE_IMAGE_NAME="smartbotic-vectorapi-build-base:debian13"
+# Client version the server deb is compiled against. Must equal the version
+# installed on the deploy target: every 2.x client shares one SONAME, so a
+# mismatch installs cleanly and only segfaults on the next service restart.
+DB_CLIENT_VERSION="${DB_CLIENT_VERSION:-2.11.1-1}"
 BUILD_JOBS="${BUILD_JOBS:-$(nproc)}"
 DEB_REPO_DIR="${DEB_REPO_DIR:-/data/dev/smartbotics/smartbotics-deb-repo}"
 
@@ -99,6 +103,8 @@ Options:
 Environment variables:
   BUILD_JOBS           Parallel build jobs (default: nproc)
   DEB_REPO_DIR         Path to smartbotics-deb-repo (default: /data/dev/smartbotics/smartbotics-deb-repo)
+  DB_CLIENT_VERSION    libsmartbotic-db-client version to build against; must match
+                       the deploy target (default: 2.11.1-1)
 EOF
     exit 0
 }
@@ -263,6 +269,23 @@ build_docker() {
             log_info "Base image not found, building ${BASE_IMAGE_NAME}..."
         fi
 
+        # Publishing re-indexes the apt pool, so the pinned client version is
+        # usually gone from the repo index. Vendor the .debs from the local
+        # deb-repo staging dir when they are there; otherwise the image falls
+        # back to installing that version from the repo.
+        local vendor_dir="$PROJECT_DIR/packaging/vendor"
+        rm -f "$vendor_dir"/*.deb
+        local found=0
+        for pkg in libsmartbotic-db-client libsmartbotic-db-client-dev; do
+            local deb="$DEB_REPO_DIR/dist/${pkg}_${DB_CLIENT_VERSION}_amd64.deb"
+            if [[ -f "$deb" ]]; then cp "$deb" "$vendor_dir/"; found=$((found + 1)); fi
+        done
+        if [[ $found -eq 2 ]]; then
+            log_info "Pinning db client ${DB_CLIENT_VERSION} from ${DEB_REPO_DIR}/dist"
+        else
+            log_warn "db client ${DB_CLIENT_VERSION} not found locally; the image will try the apt repo"
+        fi
+
         local base_cache_args=()
         if [[ $NO_CACHE -eq 1 ]]; then
             base_cache_args+=("--no-cache")
@@ -273,6 +296,7 @@ build_docker() {
             -t "$BASE_IMAGE_NAME" \
             --build-arg "REPO_USER=${REPO_USER}" \
             --build-arg "REPO_PASS=${REPO_PASS}" \
+            --build-arg "DB_CLIENT_VERSION=${DB_CLIENT_VERSION}" \
             "${base_cache_args[@]+"${base_cache_args[@]}"}" \
             "$PROJECT_DIR"
         log_success "Base image built: ${BASE_IMAGE_NAME}"

+ 0 - 0
packaging/vendor/.gitkeep