deb update
This commit is contained in:
parent
762b586242
commit
5f430155b7
@ -35,14 +35,14 @@ apt update
|
||||
apt install -y clang build-essential libpcre2-dev mariadb-client libmariadb-dev curl rsync ca-certificates
|
||||
```
|
||||
|
||||
UCE also requires two toolchains that are not vendored in this repository:
|
||||
UCE also requires two non-vendored dependencies. WASI SDK is load-bearing at runtime because UCE compiles units on demand during requests and during proactive startup scans.
|
||||
|
||||
- **Wasmtime C API / C++ headers** at `/opt/wasmtime` by default. `scripts/build_linux.sh` expects:
|
||||
- `/opt/wasmtime/include/wasmtime.hh`
|
||||
- `/opt/wasmtime/include/wasmtime/*.h`
|
||||
- `/opt/wasmtime/lib/libwasmtime.so`
|
||||
|
||||
- **WASI SDK** at `/opt/wasi-sdk` by default. `scripts/build_core_wasm.sh` and `scripts/compile_wasm_unit` expect:
|
||||
- **Pinned WASI SDK** at `/opt/wasi-sdk` by default. `scripts/build_core_wasm.sh` and request-time `scripts/compile_wasm_unit` expect:
|
||||
- `/opt/wasi-sdk/bin/clang++`
|
||||
- `/opt/wasi-sdk/bin/wasm-ld`
|
||||
- `/opt/wasi-sdk/bin/llvm-objcopy`
|
||||
@ -85,11 +85,11 @@ bin/uce_fastcgi.linux.bin
|
||||
|
||||
### Installing Wasmtime and WASI SDK
|
||||
|
||||
The UCE build does not download these dependencies for you. Install them through your distro if it provides compatible development packages, or unpack pinned release archives under `/opt/wasmtime` and `/opt/wasi-sdk`.
|
||||
The UCE build does not download these dependencies for you. Install Wasmtime through a compatible distro package or a pinned upstream C API archive. Install WASI SDK with UCE's pinned installer, or unpack the same pinned archive under `/opt/wasi-sdk`.
|
||||
|
||||
Do not use `curl | sh` installers in production setup scripts. Download archives from the upstream release pages, verify checksums/signatures when available, and record the exact versions in your deployment notes. Avoid installing a release published in the last few days unless you have reviewed it separately.
|
||||
|
||||
The expected directory shape is:
|
||||
The expected directories are:
|
||||
|
||||
```text
|
||||
/opt/wasmtime/include/wasmtime.hh
|
||||
@ -101,7 +101,17 @@ The expected directory shape is:
|
||||
/opt/wasi-sdk/bin/llvm-objcopy
|
||||
```
|
||||
|
||||
Example install flow using pinned archive files you have already chosen and verified:
|
||||
Install the WASI SDK:
|
||||
|
||||
```bash
|
||||
cd /opt/uce
|
||||
scripts/install_wasi_sdk.sh
|
||||
scripts/install_wasi_sdk.sh --check-only
|
||||
```
|
||||
|
||||
The current pin is documented in `docs/wasi-sdk-toolchain.md`. The script verifies the archive SHA256 before installing and updates `/opt/wasi-sdk` to point at the pinned versioned directory.
|
||||
|
||||
For Wasmtime, use a compatible distro package or an upstream C API archive. Example flow using an archive you have already chosen and verified:
|
||||
|
||||
```bash
|
||||
mkdir -p /opt /tmp/uce-deps
|
||||
@ -113,12 +123,6 @@ cd /tmp/uce-deps
|
||||
sha256sum -c wasmtime-c-api.sha256
|
||||
mkdir -p /opt/wasmtime
|
||||
tar -xf wasmtime-*-c-api*.tar.* -C /opt/wasmtime --strip-components=1
|
||||
|
||||
# Download the WASI SDK archive for your architecture from the upstream release
|
||||
# page, then verify its checksum before unpacking.
|
||||
sha256sum -c wasi-sdk.sha256
|
||||
mkdir -p /opt/wasi-sdk
|
||||
tar -xf wasi-sdk-*.tar.* -C /opt/wasi-sdk --strip-components=1
|
||||
```
|
||||
|
||||
After unpacking, verify the tools UCE needs. Also record the exact Wasmtime and WASI SDK versions used. The native build embeds an rpath for `$WASMTIME_HOME/lib`, so the service environment should use the same `WASMTIME_HOME` value used during build.
|
||||
@ -200,7 +204,7 @@ Important settings:
|
||||
- `BIN_DIRECTORY` stores generated C++, wasm artifacts, compile output, and runtime caches.
|
||||
- `TMP_UPLOAD_PATH` and `SESSION_PATH` must be writable by the runtime.
|
||||
- `HTTP_PORT` is the built-in HTTP/WebSocket listener used for WebSocket upgrade traffic and direct local probes. Bind/firewall it for local access only; nginx/Apache should be the public entry point.
|
||||
- `WASM_COMPILE_SCRIPT` must point to `scripts/compile_wasm_unit` unless you provide an equivalent compiler. Relative paths are resolved from the runtime root/`COMPILER_SYS_PATH`. That script calls `scripts/check_unit_wasm.py` after linking each unit.
|
||||
- `WASM_COMPILE_SCRIPT` must point to `scripts/compile_wasm_unit` unless you provide an equivalent compiler. Relative paths are resolved from the runtime root/`COMPILER_SYS_PATH`. That script calls `scripts/check_unit_wasm.py` after linking each unit and uses the pinned WASI SDK on every deployment host.
|
||||
- `WASM_CORE_PATH` must point at the built `core.wasm` file.
|
||||
|
||||
After editing settings, restart UCE:
|
||||
@ -265,6 +269,34 @@ systemctl daemon-reload
|
||||
systemctl enable --now uce.service
|
||||
```
|
||||
|
||||
### Debian package build
|
||||
|
||||
To build a Debian package from the repository root:
|
||||
|
||||
```bash
|
||||
bash scripts/make_deb.sh 0.1.2
|
||||
```
|
||||
|
||||
The Debian package creator bundles WASI SDK and Wasmtime by default when `/opt/wasi-sdk` and `/opt/wasmtime` are present. Verify the pinned SDK before building:
|
||||
|
||||
```bash
|
||||
scripts/install_wasi_sdk.sh --check-only
|
||||
bash scripts/make_deb.sh 0.1.2
|
||||
```
|
||||
|
||||
This includes the resolved `/opt/wasi-sdk-...` tree, `/opt/wasi-sdk` symlink, resolved `/opt/wasmtime-...` tree, and `/opt/wasmtime` symlink in the package. It makes the package large, but keeps request-time unit compilation and runtime linking tied to the toolchain versions that passed the test suite. Set `UCE_DEB_BUNDLE_WASI_SDK=0` or `UCE_DEB_BUNDLE_WASMTIME=0` only if your deployment provides those exact dependencies separately.
|
||||
|
||||
### RPM package build
|
||||
|
||||
To build an RPM package from the repository root, install `rpmbuild` on the packaging host, verify the pinned SDK, then run:
|
||||
|
||||
```bash
|
||||
scripts/install_wasi_sdk.sh --check-only
|
||||
bash scripts/make_rpm.sh 0.1.2
|
||||
```
|
||||
|
||||
The RPM creator mirrors the Debian package layout: runtime files under `/usr/lib/uce`, public files under `/var/www/html`, config under `/etc/uce/settings.cfg`, systemd unit under `/usr/lib/systemd/system/uce.service`, and bundled `/opt/wasi-sdk` plus `/opt/wasmtime` trees by default. Set `UCE_RPM_BUNDLE_WASI_SDK=0` or `UCE_RPM_BUNDLE_WASMTIME=0` only if your deployment provides those exact dependencies separately.
|
||||
|
||||
## How request routing works
|
||||
|
||||
### Static files
|
||||
@ -585,6 +617,7 @@ PY
|
||||
- Set `HTTP_DOCUMENT_ROOT` when the web root is outside the runtime working directory. The built-in HTTP/WebSocket listener resolves upgrade paths from this setting.
|
||||
- Do not expose `CLI_SOCKET_PATH` or `HTTP_PORT` as public entry points. The public path should be nginx/Apache.
|
||||
- Do not trust `Script-Filename` request headers from direct HTTP clients. The built-in HTTP listener resolves from `HTTP_DOCUMENT_ROOT` and rejects `..` path segments.
|
||||
- WASI SDK is a deployment/runtime dependency, not just a developer build tool. UCE compiles units to wasm on demand during requests and during proactive startup scans, so each host must use the pinned SDK version documented in `docs/wasi-sdk-toolchain.md`.
|
||||
- After toolchain or compile-script fixes, clear stale failed artifacts under `BIN_DIRECTORY`; otherwise a later request may report an old compile failure.
|
||||
|
||||
## Troubleshooting
|
||||
@ -625,7 +658,7 @@ Common compile footguns:
|
||||
|
||||
- `WASM_COMPILE_SCRIPT` is unset or points at a removed script such as `scripts/compile`; set it to `scripts/compile_wasm_unit`.
|
||||
- `scripts/check_unit_wasm.py` is missing or not executable; `scripts/compile_wasm_unit` calls it after linking each unit.
|
||||
- `WASI_SDK` does not point at a tree with `clang++`, `wasm-ld`, and `llvm-objcopy`.
|
||||
- `WASI_SDK` does not point at the pinned tree with `clang++`, `wasm-ld`, `llvm-objcopy`, and `llvm-nm`; run `scripts/install_wasi_sdk.sh --check-only`.
|
||||
- `WASMTIME_HOME` does not point at a tree with Wasmtime headers and `libwasmtime.so`.
|
||||
- A previous failed compile left stale `.compile.txt`, `.wasm-check.txt`, or partial `.wasm` files under `BIN_DIRECTORY`.
|
||||
|
||||
|
||||
55
docs/wasi-sdk-toolchain.md
Normal file
55
docs/wasi-sdk-toolchain.md
Normal file
@ -0,0 +1,55 @@
|
||||
# WASI SDK Toolchain Pin
|
||||
|
||||
UCE treats WASI SDK as a deployment/runtime dependency, not just a developer build tool.
|
||||
|
||||
The runtime compiles `.uce` units to wasm on demand during requests and during the proactive compiler scan. That means every deployment host must have the same compiler/linker toolchain available, and the generated `.wasm`/`.cwasm` artifacts are tied to that toolchain version and UCE unit ABI version.
|
||||
|
||||
## Current pin
|
||||
|
||||
- Upstream: <https://github.com/WebAssembly/wasi-sdk>
|
||||
- Release tag: `wasi-sdk-33`
|
||||
- Version: `33.0`
|
||||
- Linux x86_64 archive: `wasi-sdk-33.0-x86_64-linux.tar.gz`
|
||||
- URL: `https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-33/wasi-sdk-33.0-x86_64-linux.tar.gz`
|
||||
- SHA256: `0ba8b5bfaeb2adf3f29bab5841d76cf5318ab8e1642ea195f88baba1abd47bce`
|
||||
- Expected install symlink: `/opt/wasi-sdk`
|
||||
- Expected resolved path: `/opt/wasi-sdk-33.0-x86_64-linux`
|
||||
|
||||
Install or verify with:
|
||||
|
||||
```bash
|
||||
scripts/install_wasi_sdk.sh
|
||||
scripts/install_wasi_sdk.sh --check-only
|
||||
```
|
||||
|
||||
## Required tools
|
||||
|
||||
UCE expects these executables on each deployment host:
|
||||
|
||||
```text
|
||||
/opt/wasi-sdk/bin/clang++
|
||||
/opt/wasi-sdk/bin/wasm-ld
|
||||
/opt/wasi-sdk/bin/llvm-objcopy
|
||||
/opt/wasi-sdk/bin/llvm-nm
|
||||
```
|
||||
|
||||
`llvm-nm` is used by `scripts/check_unit_wasm.py`, which is called by `scripts/compile_wasm_unit` after linking each unit.
|
||||
|
||||
## Upgrade policy
|
||||
|
||||
Treat WASI SDK upgrades like runtime dependency upgrades:
|
||||
|
||||
1. Update `scripts/install_wasi_sdk.sh` version, URL, and SHA256.
|
||||
2. Record the new release and checksum here.
|
||||
3. Rebuild `bin/wasm/core.wasm` with `scripts/build_core_wasm.sh`.
|
||||
4. Rebuild the native runtime with `scripts/build_linux.sh`.
|
||||
5. Clear or invalidate stale unit wasm artifacts by bumping `UCE_UNIT_ABI_VERSION` when required, or by removing affected generated artifacts under `BIN_DIRECTORY`.
|
||||
6. Run the full CLI suite including wasm kill tests:
|
||||
|
||||
```bash
|
||||
scripts/run_cli_tests.sh --include-wasm-kill
|
||||
```
|
||||
|
||||
## Known footgun
|
||||
|
||||
WASI SDK 33's `llvm-nm` was observed to crash on a degenerate but valid unit module with no exported handlers. `scripts/check_unit_wasm.py` treats that specific validator-tool crash as a skipped allocator-definition scan while still rejecting forbidden allocator exports and other ABI violations. This is one reason the toolchain is pinned instead of relying on whatever `/opt/wasi-sdk` happens to contain.
|
||||
@ -3,7 +3,7 @@ Version: @VERSION@
|
||||
Section: web
|
||||
Priority: optional
|
||||
Architecture: @ARCH@
|
||||
Depends: bash, clang, libmariadb-dev | default-libmysqlclient-dev, systemd
|
||||
Depends: bash, python3, curl, systemd, libpcre2-8-0, zlib1g, libssl3, libstdc++6, libgcc-s1, libmariadb3 | libmysqlclient21 | libmysqlclient24
|
||||
Maintainer: Udo Schroeter <udo@openfu.com>
|
||||
Installed-Size: @INSTALLED_SIZE@
|
||||
Description: UCE FastCGI runtime and live-compiling C++ web environment
|
||||
|
||||
@ -5,6 +5,7 @@ if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
if [ "$1" = "configure" ]; then
|
||||
systemctl enable uce.service >/dev/null 2>&1 || true
|
||||
systemctl restart uce.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@ -11,7 +11,6 @@ StateDirectory=uce
|
||||
CacheDirectory=uce
|
||||
ExecStartPre=/usr/bin/mkdir -p /var/cache/uce/work /var/lib/uce/uploads /var/lib/uce/sessions
|
||||
ExecStartPre=/usr/bin/rm -f /run/uce/fastcgi.sock
|
||||
ExecStartPre=/usr/bin/bash /usr/lib/uce/scripts/build_linux.sh
|
||||
ExecStart=/usr/lib/uce/bin/uce_fastcgi.linux.bin
|
||||
ExecStopPost=/usr/bin/rm -f /run/uce/fastcgi.sock
|
||||
Restart=always
|
||||
|
||||
98
scripts/install_wasi_sdk.sh
Executable file
98
scripts/install_wasi_sdk.sh
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Install the pinned WASI SDK used by UCE's request-time wasm compiler.
|
||||
# This is a runtime dependency: UCE compiles .uce units on demand and during
|
||||
# proactive startup scans, so every deployment host needs the same toolchain.
|
||||
|
||||
WASI_SDK_VERSION="${WASI_SDK_VERSION:-33.0}"
|
||||
WASI_SDK_RELEASE_TAG="${WASI_SDK_RELEASE_TAG:-wasi-sdk-33}"
|
||||
WASI_SDK_ARCHIVE="${WASI_SDK_ARCHIVE:-wasi-sdk-33.0-x86_64-linux.tar.gz}"
|
||||
WASI_SDK_SHA256="${WASI_SDK_SHA256:-0ba8b5bfaeb2adf3f29bab5841d76cf5318ab8e1642ea195f88baba1abd47bce}"
|
||||
WASI_SDK_URL="${WASI_SDK_URL:-https://github.com/WebAssembly/wasi-sdk/releases/download/${WASI_SDK_RELEASE_TAG}/${WASI_SDK_ARCHIVE}}"
|
||||
INSTALL_BASE="${INSTALL_BASE:-/opt}"
|
||||
INSTALL_DIR="${WASI_SDK_INSTALL_DIR:-${INSTALL_BASE}/wasi-sdk-${WASI_SDK_VERSION}-x86_64-linux}"
|
||||
SYMLINK_PATH="${WASI_SDK_SYMLINK:-${INSTALL_BASE}/wasi-sdk}"
|
||||
CACHE_DIR="${WASI_SDK_CACHE_DIR:-/tmp/uce-deps}"
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: scripts/install_wasi_sdk.sh [--check-only]
|
||||
|
||||
Installs pinned WASI SDK ${WASI_SDK_VERSION} for UCE request-time unit compilation.
|
||||
|
||||
Environment overrides:
|
||||
WASI_SDK_VERSION ${WASI_SDK_VERSION}
|
||||
WASI_SDK_RELEASE_TAG ${WASI_SDK_RELEASE_TAG}
|
||||
WASI_SDK_ARCHIVE ${WASI_SDK_ARCHIVE}
|
||||
WASI_SDK_SHA256 ${WASI_SDK_SHA256}
|
||||
WASI_SDK_URL ${WASI_SDK_URL}
|
||||
WASI_SDK_INSTALL_DIR ${INSTALL_DIR}
|
||||
WASI_SDK_SYMLINK ${SYMLINK_PATH}
|
||||
WASI_SDK_CACHE_DIR ${CACHE_DIR}
|
||||
EOF
|
||||
}
|
||||
|
||||
check_only=0
|
||||
if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
elif [[ "${1:-}" == "--check-only" ]]; then
|
||||
check_only=1
|
||||
elif [[ $# -gt 0 ]]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "Required command not found: $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
verify_tree() {
|
||||
local root="$1"
|
||||
for tool in clang++ wasm-ld llvm-objcopy llvm-nm; do
|
||||
if [[ ! -x "$root/bin/$tool" ]]; then
|
||||
echo "Missing WASI SDK tool: $root/bin/$tool" >&2
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
"$root/bin/clang++" --version | head -n 1
|
||||
}
|
||||
|
||||
if [[ $check_only -eq 1 ]]; then
|
||||
verify_tree "${WASI_SDK:-$SYMLINK_PATH}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
require_command curl
|
||||
require_command sha256sum
|
||||
require_command tar
|
||||
require_command mkdir
|
||||
require_command ln
|
||||
|
||||
mkdir -p "$CACHE_DIR" "$INSTALL_BASE"
|
||||
archive_path="$CACHE_DIR/$WASI_SDK_ARCHIVE"
|
||||
|
||||
if [[ ! -f "$archive_path" ]]; then
|
||||
echo "Downloading $WASI_SDK_URL"
|
||||
curl -fL --proto '=https' --tlsv1.2 -o "$archive_path.tmp" "$WASI_SDK_URL"
|
||||
mv "$archive_path.tmp" "$archive_path"
|
||||
fi
|
||||
|
||||
printf '%s %s\n' "$WASI_SDK_SHA256" "$archive_path" | sha256sum -c -
|
||||
|
||||
rm -rf -- "$INSTALL_DIR.tmp"
|
||||
mkdir -p "$INSTALL_DIR.tmp"
|
||||
tar -xf "$archive_path" -C "$INSTALL_DIR.tmp" --strip-components=1
|
||||
verify_tree "$INSTALL_DIR.tmp"
|
||||
|
||||
rm -rf -- "$INSTALL_DIR"
|
||||
mv "$INSTALL_DIR.tmp" "$INSTALL_DIR"
|
||||
ln -sfn "$INSTALL_DIR" "$SYMLINK_PATH"
|
||||
|
||||
echo "Installed WASI SDK at $INSTALL_DIR"
|
||||
echo "Updated symlink $SYMLINK_PATH -> $INSTALL_DIR"
|
||||
verify_tree "$SYMLINK_PATH"
|
||||
@ -13,8 +13,11 @@ Usage:
|
||||
scripts/make_deb.sh VERSION
|
||||
|
||||
Environment:
|
||||
UCE_DEB_REVISION Debian package revision suffix (default: 1)
|
||||
UCE_DEB_ARCH Override package architecture
|
||||
UCE_DEB_REVISION Debian package revision suffix (default: 1)
|
||||
UCE_DEB_ARCH Override package architecture
|
||||
UCE_DEB_WEBROOT Public web root staged into the package (default: /var/www/html)
|
||||
UCE_DEB_BUNDLE_WASI_SDK Bundle pinned /opt/wasi-sdk into the package (default: 1)
|
||||
UCE_DEB_BUNDLE_WASMTIME Bundle /opt/wasmtime into the package (default: 1)
|
||||
EOF
|
||||
}
|
||||
|
||||
@ -47,12 +50,37 @@ validate_version() {
|
||||
|
||||
copy_payload() {
|
||||
local destination="$1"
|
||||
local webroot="$2"
|
||||
local stage_dir="$3"
|
||||
local path
|
||||
for path in LICENSE README.md codesearch bin scripts site src; do
|
||||
for path in LICENSE README.md codesearch bin scripts src docs; do
|
||||
cp -a "$REPO_ROOT/$path" "$destination/"
|
||||
done
|
||||
mkdir -p "$destination/etc"
|
||||
mkdir -p "$destination/etc" "$stage_dir$webroot"
|
||||
cp -a "$REPO_ROOT/etc/uce" "$destination/etc/"
|
||||
cp -a "$REPO_ROOT/site/." "$stage_dir$webroot/"
|
||||
}
|
||||
|
||||
write_packaged_settings() {
|
||||
local output_file="$1"
|
||||
local webroot="$2"
|
||||
python3 - "$REPO_ROOT/etc/uce/settings.cfg" "$output_file" "$webroot" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
src, dst, webroot = sys.argv[1:4]
|
||||
s = Path(src).read_text()
|
||||
replacements = {
|
||||
"SITE_DIRECTORY=site": f"SITE_DIRECTORY={webroot}",
|
||||
"WASM_CORE_PATH=/Code/uce.openfu.com/uce/bin/wasm/core.wasm": "WASM_CORE_PATH=/usr/lib/uce/bin/wasm/core.wasm",
|
||||
"HTTP_DOCUMENT_ROOT=": f"HTTP_DOCUMENT_ROOT={webroot}",
|
||||
}
|
||||
for old, new in replacements.items():
|
||||
if old in s:
|
||||
s = s.replace(old, new)
|
||||
if "WASM_COMPILE_SCRIPT=" not in s:
|
||||
s += "\nWASM_COMPILE_SCRIPT=scripts/compile_wasm_unit\n"
|
||||
Path(dst).write_text(s)
|
||||
PY
|
||||
}
|
||||
|
||||
write_control_file() {
|
||||
@ -69,11 +97,49 @@ write_control_file() {
|
||||
"$DEB_ASSET_DIR/control.in" > "$output_file"
|
||||
}
|
||||
|
||||
bundle_wasi_sdk() {
|
||||
local stage_dir="$1"
|
||||
local wasi_root="${WASI_SDK:-/opt/wasi-sdk}"
|
||||
if [[ "${UCE_DEB_BUNDLE_WASI_SDK:-1}" != "1" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ ! -x "$wasi_root/bin/clang++" || ! -x "$wasi_root/bin/wasm-ld" || ! -x "$wasi_root/bin/llvm-nm" ]]; then
|
||||
echo "UCE_DEB_BUNDLE_WASI_SDK=1 but WASI_SDK does not point at a complete SDK: $wasi_root" >&2
|
||||
exit 1
|
||||
fi
|
||||
local resolved
|
||||
resolved="$(readlink -f "$wasi_root")"
|
||||
local base
|
||||
base="$(basename "$resolved")"
|
||||
mkdir -p "$stage_dir/opt"
|
||||
cp -a "$resolved" "$stage_dir/opt/$base"
|
||||
ln -sfn "$base" "$stage_dir/opt/wasi-sdk"
|
||||
}
|
||||
|
||||
bundle_wasmtime() {
|
||||
local stage_dir="$1"
|
||||
local wasmtime_root="${WASMTIME_HOME:-/opt/wasmtime}"
|
||||
if [[ "${UCE_DEB_BUNDLE_WASMTIME:-1}" != "1" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ ! -f "$wasmtime_root/include/wasmtime.hh" || ! -f "$wasmtime_root/lib/libwasmtime.so" ]]; then
|
||||
echo "UCE_DEB_BUNDLE_WASMTIME=1 but WASMTIME_HOME does not point at a complete C API tree: $wasmtime_root" >&2
|
||||
exit 1
|
||||
fi
|
||||
local resolved
|
||||
resolved="$(readlink -f "$wasmtime_root")"
|
||||
local base
|
||||
base="$(basename "$resolved")"
|
||||
mkdir -p "$stage_dir/opt"
|
||||
cp -a "$resolved" "$stage_dir/opt/$base"
|
||||
ln -sfn "$base" "$stage_dir/opt/wasmtime"
|
||||
}
|
||||
|
||||
write_md5sums() {
|
||||
local stage_dir="$1"
|
||||
(
|
||||
cd "$stage_dir"
|
||||
find usr etc lib -type f -print0 | sort -z | xargs -0 md5sum > DEBIAN/md5sums
|
||||
find usr etc lib opt -type f -print0 2>/dev/null | sort -z | xargs -0 --no-run-if-empty md5sum > DEBIAN/md5sums
|
||||
)
|
||||
}
|
||||
|
||||
@ -106,6 +172,7 @@ PACKAGE_BASENAME="${PACKAGE_NAME}_${PACKAGE_VERSION}_${ARCH}"
|
||||
STAGE_DIR="$REPO_ROOT/pkg/$PACKAGE_BASENAME"
|
||||
DEBIAN_DIR="$STAGE_DIR/DEBIAN"
|
||||
INSTALL_ROOT="$STAGE_DIR/usr/lib/uce"
|
||||
WEBROOT="${UCE_DEB_WEBROOT:-/var/www/html}"
|
||||
DIST_DIR="$REPO_ROOT/dist"
|
||||
OUTPUT_DEB="$DIST_DIR/$PACKAGE_BASENAME.deb"
|
||||
|
||||
@ -117,9 +184,11 @@ bash "$REPO_ROOT/scripts/build_linux.sh"
|
||||
rm -rf -- "$STAGE_DIR"
|
||||
mkdir -p "$DEBIAN_DIR" "$INSTALL_ROOT" "$STAGE_DIR/etc/uce" "$STAGE_DIR/lib/systemd/system" "$DIST_DIR"
|
||||
|
||||
copy_payload "$INSTALL_ROOT"
|
||||
copy_payload "$INSTALL_ROOT" "$WEBROOT" "$STAGE_DIR"
|
||||
bundle_wasi_sdk "$STAGE_DIR"
|
||||
bundle_wasmtime "$STAGE_DIR"
|
||||
|
||||
install -m 0644 "$REPO_ROOT/etc/uce/settings.cfg" "$STAGE_DIR/etc/uce/settings.cfg"
|
||||
write_packaged_settings "$STAGE_DIR/etc/uce/settings.cfg" "$WEBROOT"
|
||||
install -m 0644 "$DEB_ASSET_DIR/uce.service" "$STAGE_DIR/lib/systemd/system/uce.service"
|
||||
install -m 0644 "$DEB_ASSET_DIR/conffiles" "$DEBIAN_DIR/conffiles"
|
||||
install -m 0755 "$DEB_ASSET_DIR/postinst" "$DEBIAN_DIR/postinst"
|
||||
|
||||
230
scripts/make_rpm.sh
Executable file
230
scripts/make_rpm.sh
Executable file
@ -0,0 +1,230 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
PACKAGE_NAME="uce"
|
||||
RELEASE="${UCE_RPM_RELEASE:-1}"
|
||||
WEBROOT="${UCE_RPM_WEBROOT:-/var/www/html}"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
scripts/make_rpm.sh VERSION
|
||||
|
||||
Environment:
|
||||
UCE_RPM_RELEASE RPM release suffix (default: 1)
|
||||
UCE_RPM_ARCH Override RPM architecture
|
||||
UCE_RPM_WEBROOT Public web root staged into the package (default: /var/www/html)
|
||||
UCE_RPM_BUNDLE_WASI_SDK Bundle pinned /opt/wasi-sdk into the package (default: 1)
|
||||
UCE_RPM_BUNDLE_WASMTIME Bundle /opt/wasmtime into the package (default: 1)
|
||||
EOF
|
||||
}
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
echo "Required command not found: $1" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_version() {
|
||||
local version="$1"
|
||||
if [[ ! "$version" =~ ^[0-9][A-Za-z0-9._+~]*$ ]]; then
|
||||
echo "Invalid RPM version string: $version" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
resolve_arch() {
|
||||
if [[ -n "${UCE_RPM_ARCH:-}" ]]; then
|
||||
printf '%s\n' "$UCE_RPM_ARCH"
|
||||
return
|
||||
fi
|
||||
uname -m
|
||||
}
|
||||
|
||||
copy_payload() {
|
||||
local destination="$1"
|
||||
local webroot="$2"
|
||||
local stage_dir="$3"
|
||||
local path
|
||||
for path in LICENSE README.md codesearch bin scripts src docs; do
|
||||
cp -a "$REPO_ROOT/$path" "$destination/"
|
||||
done
|
||||
mkdir -p "$destination/etc" "$stage_dir$webroot"
|
||||
cp -a "$REPO_ROOT/etc/uce" "$destination/etc/"
|
||||
cp -a "$REPO_ROOT/site/." "$stage_dir$webroot/"
|
||||
}
|
||||
|
||||
write_packaged_settings() {
|
||||
local output_file="$1"
|
||||
local webroot="$2"
|
||||
python3 - "$REPO_ROOT/etc/uce/settings.cfg" "$output_file" "$webroot" <<'PY'
|
||||
from pathlib import Path
|
||||
import sys
|
||||
src, dst, webroot = sys.argv[1:4]
|
||||
s = Path(src).read_text()
|
||||
replacements = {
|
||||
"SITE_DIRECTORY=site": f"SITE_DIRECTORY={webroot}",
|
||||
"WASM_CORE_PATH=/Code/uce.openfu.com/uce/bin/wasm/core.wasm": "WASM_CORE_PATH=/usr/lib/uce/bin/wasm/core.wasm",
|
||||
"HTTP_DOCUMENT_ROOT=": f"HTTP_DOCUMENT_ROOT={webroot}",
|
||||
}
|
||||
for old, new in replacements.items():
|
||||
if old in s:
|
||||
s = s.replace(old, new)
|
||||
if "WASM_COMPILE_SCRIPT=" not in s:
|
||||
s += "\nWASM_COMPILE_SCRIPT=scripts/compile_wasm_unit\n"
|
||||
Path(dst).write_text(s)
|
||||
PY
|
||||
}
|
||||
|
||||
bundle_wasi_sdk() {
|
||||
local stage_dir="$1"
|
||||
local wasi_root="${WASI_SDK:-/opt/wasi-sdk}"
|
||||
if [[ "${UCE_RPM_BUNDLE_WASI_SDK:-1}" != "1" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ ! -x "$wasi_root/bin/clang++" || ! -x "$wasi_root/bin/wasm-ld" || ! -x "$wasi_root/bin/llvm-nm" ]]; then
|
||||
echo "UCE_RPM_BUNDLE_WASI_SDK=1 but WASI_SDK does not point at a complete SDK: $wasi_root" >&2
|
||||
exit 1
|
||||
fi
|
||||
local resolved base
|
||||
resolved="$(readlink -f "$wasi_root")"
|
||||
base="$(basename "$resolved")"
|
||||
mkdir -p "$stage_dir/opt"
|
||||
cp -a "$resolved" "$stage_dir/opt/$base"
|
||||
ln -sfn "$base" "$stage_dir/opt/wasi-sdk"
|
||||
}
|
||||
|
||||
bundle_wasmtime() {
|
||||
local stage_dir="$1"
|
||||
local wasmtime_root="${WASMTIME_HOME:-/opt/wasmtime}"
|
||||
if [[ "${UCE_RPM_BUNDLE_WASMTIME:-1}" != "1" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ ! -f "$wasmtime_root/include/wasmtime.hh" || ! -f "$wasmtime_root/lib/libwasmtime.so" ]]; then
|
||||
echo "UCE_RPM_BUNDLE_WASMTIME=1 but WASMTIME_HOME does not point at a complete C API tree: $wasmtime_root" >&2
|
||||
exit 1
|
||||
fi
|
||||
local resolved base
|
||||
resolved="$(readlink -f "$wasmtime_root")"
|
||||
base="$(basename "$resolved")"
|
||||
mkdir -p "$stage_dir/opt"
|
||||
cp -a "$resolved" "$stage_dir/opt/$base"
|
||||
ln -sfn "$base" "$stage_dir/opt/wasmtime"
|
||||
}
|
||||
|
||||
if [[ $# -ne 1 ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
VERSION="$1"
|
||||
validate_version "$VERSION"
|
||||
|
||||
require_command bash
|
||||
require_command rpmbuild
|
||||
require_command find
|
||||
require_command cp
|
||||
require_command tar
|
||||
require_command sed
|
||||
require_command python3
|
||||
require_command readlink
|
||||
|
||||
ARCH="$(resolve_arch)"
|
||||
PACKAGE_VERSION="${VERSION}-${RELEASE}"
|
||||
BUILD_ROOT="$REPO_ROOT/pkg/rpm-build"
|
||||
STAGE_DIR="$BUILD_ROOT/stage"
|
||||
RPMBUILD_DIR="$BUILD_ROOT/rpmbuild"
|
||||
INSTALL_ROOT="$STAGE_DIR/usr/lib/uce"
|
||||
SPEC_FILE="$RPMBUILD_DIR/SPECS/$PACKAGE_NAME.spec"
|
||||
DIST_DIR="$REPO_ROOT/dist"
|
||||
|
||||
bash "$REPO_ROOT/scripts/build_linux.sh"
|
||||
|
||||
rm -rf -- "$BUILD_ROOT"
|
||||
mkdir -p "$INSTALL_ROOT" "$STAGE_DIR/etc/uce" "$STAGE_DIR/usr/lib/systemd/system" "$RPMBUILD_DIR"/{BUILD,RPMS,SOURCES,SPECS,SRPMS} "$DIST_DIR"
|
||||
|
||||
copy_payload "$INSTALL_ROOT" "$WEBROOT" "$STAGE_DIR"
|
||||
bundle_wasi_sdk "$STAGE_DIR"
|
||||
bundle_wasmtime "$STAGE_DIR"
|
||||
write_packaged_settings "$STAGE_DIR/etc/uce/settings.cfg" "$WEBROOT"
|
||||
install -m 0644 "$REPO_ROOT/scripts/deb/uce.service" "$STAGE_DIR/usr/lib/systemd/system/uce.service"
|
||||
|
||||
(
|
||||
cd "$STAGE_DIR"
|
||||
tar --sort=name --mtime='UTC 2026-01-01' --owner=0 --group=0 --numeric-owner -czf "$RPMBUILD_DIR/SOURCES/$PACKAGE_NAME-$VERSION.tar.gz" .
|
||||
)
|
||||
|
||||
cat > "$SPEC_FILE" <<EOF
|
||||
Name: $PACKAGE_NAME
|
||||
Version: $VERSION
|
||||
Release: $RELEASE%{?dist}
|
||||
Summary: UCE FastCGI runtime and live-compiling C++ web environment
|
||||
License: GPL-3.0-or-later
|
||||
URL: https://example.com/uce
|
||||
BuildArch: $ARCH
|
||||
Requires: bash
|
||||
Requires: python3
|
||||
Requires: curl
|
||||
Requires: systemd
|
||||
Requires: pcre2
|
||||
Requires: zlib
|
||||
Requires: openssl-libs
|
||||
Requires: libstdc++
|
||||
Requires: mariadb-connector-c
|
||||
|
||||
%description
|
||||
UCE is an experimental C/C++ web runtime with FastCGI request handling,
|
||||
on-demand wasm unit compilation, and a packaged site/doc/test tree.
|
||||
|
||||
%prep
|
||||
rm -rf %{_builddir}/$PACKAGE_NAME-$VERSION
|
||||
mkdir -p %{_builddir}/$PACKAGE_NAME-$VERSION
|
||||
cd %{_builddir}/$PACKAGE_NAME-$VERSION
|
||||
tar -xzf %{_sourcedir}/$PACKAGE_NAME-$VERSION.tar.gz
|
||||
|
||||
%build
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
mkdir -p %{buildroot}
|
||||
cp -a %{_builddir}/$PACKAGE_NAME-$VERSION/. %{buildroot}/
|
||||
|
||||
%post
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
systemctl enable uce.service >/dev/null 2>&1 || true
|
||||
systemctl restart uce.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
%preun
|
||||
if [ "\$1" = "0" ] && command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl disable --now uce.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
%postun
|
||||
if command -v systemctl >/dev/null 2>&1; then
|
||||
systemctl daemon-reload >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
%files
|
||||
%license /usr/lib/uce/LICENSE
|
||||
%doc /usr/lib/uce/README.md
|
||||
%config(noreplace) /etc/uce/settings.cfg
|
||||
/usr/lib/uce
|
||||
/usr/lib/systemd/system/uce.service
|
||||
$WEBROOT
|
||||
%dir /var/cache/uce
|
||||
%dir /var/lib/uce
|
||||
/opt/*
|
||||
|
||||
%changelog
|
||||
* Mon Jun 15 2026 UCE Packager <root@localhost> - $PACKAGE_VERSION
|
||||
- Package UCE runtime with pinned deployment toolchains.
|
||||
EOF
|
||||
|
||||
rpmbuild --define "_topdir $RPMBUILD_DIR" -bb "$SPEC_FILE"
|
||||
find "$RPMBUILD_DIR/RPMS" -type f -name '*.rpm' -print -exec cp -a {} "$DIST_DIR/" \;
|
||||
find "$DIST_DIR" -maxdepth 1 -type f -name "${PACKAGE_NAME}-${VERSION}-${RELEASE}*.rpm" -print
|
||||
Loading…
x
Reference in New Issue
Block a user