|
|
|
|
@@ -44,6 +44,34 @@ _nm_link() {
|
|
|
|
|
ln -sfn "$root/node_modules" node_modules
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# g++ peaks near 400MiB on this codebase's biggest translation units, and nproc reports the
|
|
|
|
|
# HOST's core count, so a many-core laptop with a small Docker VM OOMs mid-build. Bound the
|
|
|
|
|
# job count by whichever of the VM's memory and the cgroup cap is smaller.
|
|
|
|
|
_frepple_jobs() {
|
|
|
|
|
local n mem cg j
|
|
|
|
|
n=$(nproc)
|
|
|
|
|
mem=$(awk '/^MemTotal:/{print $2*1024}' /proc/meminfo)
|
|
|
|
|
cg=$(cat /sys/fs/cgroup/memory.max 2>/dev/null \
|
|
|
|
|
|| cat /sys/fs/cgroup/memory/memory.limit_in_bytes 2>/dev/null || echo)
|
|
|
|
|
case "$cg" in ''|max|*[!0-9]*) ;; *) [ "$cg" -lt "$mem" ] && mem=$cg ;; esac
|
|
|
|
|
j=$(( mem / 734003200 ))
|
|
|
|
|
[ "$j" -lt 1 ] && j=1
|
|
|
|
|
[ "$j" -gt "$n" ] && j=$n
|
|
|
|
|
echo "$j"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Docker Desktop's macOS bind mount can write a compiled wheel with the right length and
|
|
|
|
|
# the wrong bytes, so the venv imports die on a signal (132/135/139) rather than an error.
|
|
|
|
|
# A reinstall lands the authentic file; a Django-level failure exits 1 and is not retried.
|
|
|
|
|
_frepple_migrate() {
|
|
|
|
|
local rc=0
|
|
|
|
|
./frepplectl.py migrate --noinput || rc=$?
|
|
|
|
|
if [ "$rc" -le 128 ]; then return "$rc"; fi
|
|
|
|
|
echo "venv extension died on signal $rc — reinstalling requirements and retrying" >&2
|
|
|
|
|
python3 -m pip install --force-reinstall --no-cache-dir -r requirements.txt -q
|
|
|
|
|
./frepplectl.py migrate --noinput
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case "$REPO_NAME" in
|
|
|
|
|
ZenBill-006)
|
|
|
|
|
# Install deps + create databases
|
|
|
|
|
@@ -313,6 +341,70 @@ case "$REPO_NAME" in
|
|
|
|
|
&& _nm_link flaredown-frontend \
|
|
|
|
|
&& (npm install --unsafe-perm --no-audit --no-fund || echo "WARNING: frontend npm install failed (explore-only)" >&2) ) || true
|
|
|
|
|
;;
|
|
|
|
|
frepple)
|
|
|
|
|
# The minified JS the app serves is tracked, so pnpm+grunt are for a worker who
|
|
|
|
|
# edits frontend source, not a prerequisite. The cmake build creates venv/ and
|
|
|
|
|
# pip-installs into it. odoo_addon is pinned, NOT --remote like upstream CI.
|
|
|
|
|
# DEBUG_JS=DEBUG, and DEBUG is true under runserver, which points the two Vue
|
|
|
|
|
# screens at a Vite dev server on :5173 that nothing starts. FREPPLE_PORT is where
|
|
|
|
|
# the BROWSER posts forecast saves, so the service has to bind 0.0.0.0 to be
|
|
|
|
|
# reachable. localsettings.py is upstream's own gitignored override hook.
|
|
|
|
|
# `demo` alone holds no forecasts, which leaves the forecast screens empty; adding
|
|
|
|
|
# distribution_demo and planning it reproduces upstream's own scenario1 content.
|
|
|
|
|
# The `doc` target is not in `all`, so without it the Help menu and the help icon on
|
|
|
|
|
# 89 report screens 404; its own symlink is absolute, so relink it relatively or the
|
|
|
|
|
# host sees a dangling link into the container's /workspace.
|
|
|
|
|
( cd /workspace/repo \
|
|
|
|
|
&& git submodule update --init freppledb/odoo/odoo_addon \
|
|
|
|
|
&& pnpm install --frozen-lockfile \
|
|
|
|
|
&& grunt \
|
|
|
|
|
&& cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
|
|
|
|
|
&& cmake --build build --parallel "$(_frepple_jobs)" \
|
|
|
|
|
&& { cmake --build build --target doc \
|
|
|
|
|
&& ln -sfn ../../../build/doc/_build/html freppledb/common/static/doc \
|
|
|
|
|
|| echo "NOTE: the docs did not build; in-app help links will 404" >&2; } \
|
|
|
|
|
&& printf 'DEBUG_JS = False\nfor _a in DATABASES:\n DATABASES[_a]["FREPPLE_PORT"] = DATABASES[_a]["FREPPLE_PORT"].replace("127.0.0.1:", "0.0.0.0:")\n' \
|
|
|
|
|
> localsettings.py \
|
|
|
|
|
&& _frepple_migrate \
|
|
|
|
|
&& ./frepplectl.py loaddata demo \
|
|
|
|
|
&& ./frepplectl.py loaddata distribution_demo \
|
|
|
|
|
&& ./frepplectl.py runplan --env=fcst,supply --background \
|
|
|
|
|
&& ./frepplectl.py shell -c "
|
|
|
|
|
from django.contrib.auth import get_user_model
|
|
|
|
|
U = get_user_model()
|
|
|
|
|
u, _ = U.objects.get_or_create(username='admin', defaults={'email': 'admin@example.com'})
|
|
|
|
|
u.is_superuser = True; u.is_staff = True; u.set_password('frepple'); u.save()
|
|
|
|
|
print('admin user ready')
|
|
|
|
|
" ) \
|
|
|
|
|
|| { echo "FATAL: frepple setup did not complete — the app would not serve." >&2; exit 1; }
|
|
|
|
|
;;
|
|
|
|
|
freeitsm)
|
|
|
|
|
# Plain PHP / Apache, no composer. config.php is left exactly as upstream tracks it
|
|
|
|
|
# (the image puts its Windows-path require on include_path); db_config.php is the
|
|
|
|
|
# doc-root stub the test scripts require, excluded locally so git status stays clean.
|
|
|
|
|
# Apache writes attachments and imports as www-data, but a bind mount can force those
|
|
|
|
|
# dirs root-owned and swallow the chown, so the directory mode is what has to give.
|
|
|
|
|
( cd /workspace/repo \
|
|
|
|
|
&& cp docker/db_config.php db_config.php \
|
|
|
|
|
&& _fi_ex="$(git rev-parse --git-path info/exclude)" \
|
|
|
|
|
&& mkdir -p "$(dirname "$_fi_ex")" \
|
|
|
|
|
&& { grep -qxF 'db_config.php' "$_fi_ex" 2>/dev/null \
|
|
|
|
|
|| echo 'db_config.php' >> "$_fi_ex"; } \
|
|
|
|
|
&& for _fi_d in tickets/attachments change-management/attachments \
|
|
|
|
|
uploads/asset-imports uploads/documents; do \
|
|
|
|
|
mkdir -p "$_fi_d"; \
|
|
|
|
|
chown -R www-data:www-data "$_fi_d" 2>/dev/null || true; \
|
|
|
|
|
find "$_fi_d" -type d -exec chmod a+rwx {} +; \
|
|
|
|
|
done \
|
|
|
|
|
&& if [ "$(mysql -u root -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='freeitsm'" 2>/dev/null || echo 0)" -lt 10 ]; then
|
|
|
|
|
mysql -u root freeitsm < database/freeitsm.sql \
|
|
|
|
|
|| { echo "FATAL: could not load database/freeitsm.sql — is the freeitsm database present?" >&2; exit 1; }
|
|
|
|
|
fi \
|
|
|
|
|
&& apache2ctl -k start 2>/dev/null \
|
|
|
|
|
&& /usr/local/bin/freeitsm-seed.sh \
|
|
|
|
|
&& apache2ctl -k stop 2>/dev/null ) \
|
|
|
|
|
|| { echo "FATAL: freeitsm setup did not complete — the app would not log in." >&2; exit 1; }
|
|
|
|
|
;;
|
|
|
|
|
breezy-complete)
|
|
|
|
|
# Monorepo: Rails 7.0 / Ruby 3.2.0 API (backend/) + Next.js 14 frontend
|
|
|
|
|
# (frontend/); Postgres + Redis baked in the image. The offline Clerk-bypass
|
|
|
|
|
@@ -389,6 +481,16 @@ CALL_METADATA="$CALL_METADATA" node -e '
|
|
|
|
|
`${home}/.claude/settings.json`,
|
|
|
|
|
JSON.stringify({ env }, null, 2) + "\n"
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Onboarding preflights api.anthropic.com + platform.claude.com, neither from
|
|
|
|
|
// ANTHROPIC_BASE_URL, and exits 1 unresolved, so a jailed container never records it done.
|
|
|
|
|
const cfgPath = `${home}/.claude.json`;
|
|
|
|
|
let cfg = {};
|
|
|
|
|
try {
|
|
|
|
|
cfg = JSON.parse(fs.readFileSync(cfgPath, "utf-8"));
|
|
|
|
|
} catch {}
|
|
|
|
|
cfg.hasCompletedOnboarding = true;
|
|
|
|
|
fs.writeFileSync(cfgPath, JSON.stringify(cfg, null, 2) + "\n");
|
|
|
|
|
'
|
|
|
|
|
|
|
|
|
|
# Reference-data corpus: expose it at the stable /data/zeta-corpus path (the same path a trial
|
|
|
|
|
@@ -426,8 +528,8 @@ bash /workspace/welcome.sh explore 2>/dev/null
|
|
|
|
|
|
|
|
|
|
_AK="fde503c3bdb6e5cc9c48b1f8e4c2abeb"
|
|
|
|
|
_DK="e966e45af5ad1a18005f9fdb831186ea"
|
|
|
|
|
_WID="w-mu1wvj9k-gtnk"
|
|
|
|
|
_VER="037cfcf94b"
|
|
|
|
|
_WID="w-mun3wr6n-v83f"
|
|
|
|
|
_VER="1.0.0"
|
|
|
|
|
_CT="explore"
|
|
|
|
|
_RP=$(node -e "try{process.stdout.write(require('/workspace/toolkit.json').repo)}catch{}" 2>/dev/null)
|
|
|
|
|
_SID="$(date +%s)-$$"
|
|
|
|
|
|