95 lines
4.9 KiB
Go
95 lines
4.9 KiB
Go
// Package preparation owns installation-local documents before any runtime exists.
|
|
package preparation
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/aritmolab/thothii/tools/tht/internal/safeio"
|
|
)
|
|
|
|
func Prepare(directory string) error {
|
|
if err := safeio.ValidateCanonicalPath(directory); err != nil {
|
|
return fmt.Errorf("choose an absolute canonical destination")
|
|
}
|
|
exists, err := safeio.PreflightPrivateDirectory(directory)
|
|
if err != nil || exists {
|
|
return fmt.Errorf("choose a new private directory with an existing parent; existing documents are never replaced")
|
|
}
|
|
if err := safeio.EnsurePrivateDirectory(directory); err != nil {
|
|
return fmt.Errorf("cannot create private preparation directory")
|
|
}
|
|
root := func(name string) string { return strconv.Quote(filepath.Join(directory, name)) }
|
|
installation := fmt.Sprintf(`# Installation schema v2; replace CHANGE_ME before validation.
|
|
# Paths refer to local preparation files, never to workspace Git.
|
|
schemaVersion: 2
|
|
profile: local
|
|
projectDirectory: %s
|
|
envFile: %s
|
|
shell: {mode: full, defaultLocale: en}
|
|
workspaceRepository:
|
|
remote: https://CHANGE_ME/workspaces.git
|
|
branch: main
|
|
access: https
|
|
authentication:
|
|
configDirectory: %s
|
|
modelCatalog:
|
|
defaults: {interaction: openai/gpt-4.1-mini}
|
|
embedding: {id: 'ollama/qwen3-embedding:0.6b', dimensions: 1024}
|
|
providers:
|
|
openai:
|
|
authentication: {mode: secret_env, apiKeyEnv: OPENAI_API_KEY}
|
|
session: {mode: pi_builtin}
|
|
models:
|
|
gpt-4.1-mini: {session: {}}
|
|
# Metadata generation is optional: omitted here. Configure its eligibility in this catalog.
|
|
# This Compose asset will come from the release; no application checkout is required here.
|
|
overrides: [%s]
|
|
`, strconv.Quote(directory), root("operator.env"), root("auth"), root("deploy/compose.git-https.yaml"))
|
|
environment := "# Non-secret paths and parameters; no interpolation or duplicate keys.\n"
|
|
for _, entry := range [][2]string{
|
|
{"COMPOSE_PROJECT_NAME", "thothii-local"}, {"THT_WORKSPACE_INSTALLATION_ID", "local"},
|
|
{"THT_WORKSPACE_GIT_REMOTE", "https://CHANGE_ME/workspaces.git"}, {"THT_WORKSPACE_GIT_BRANCH", "main"},
|
|
{"THT_INSTALLATION_CONFIG_SOURCE", filepath.Join(directory, "thothii-installation.yaml")},
|
|
{"THT_AUTH_CONFIG_ROOT", filepath.Join(directory, "auth")},
|
|
{"THT_SECRETS_FILE", filepath.Join(directory, "secrets", "secrets.env")},
|
|
{"PI_AUTH_FILE", filepath.Join(directory, "secrets", "pi-auth.json")},
|
|
{"THT_WORKSPACE_GIT_CREDENTIALS_FILE", filepath.Join(directory, "secrets", "git-credentials")},
|
|
{"THT_WORKSPACE_GIT_CA_FILE", filepath.Join(directory, "secrets", "git-ca.pem")},
|
|
{"THT_CATALOG_RUNTIME_PASSWORD_SOURCE", filepath.Join(directory, "secrets", "catalog-runtime-password")},
|
|
{"THT_CATALOG_MIGRATOR_PASSWORD_SOURCE", filepath.Join(directory, "secrets", "catalog-migrator-password")},
|
|
{"THOTH_HTTP_PORT", "8080"}, {"THOTH_CORE_HTTP_PORT", "8787"}, {"MAX_PI_PROCESSES", "4"},
|
|
} {
|
|
environment += entry[0] + "=" + strconv.Quote(entry[1]) + "\n"
|
|
}
|
|
bootstrap := fmt.Sprintf(`# Bootstrap input only; PostgreSQL Metadata Catalog remains the runtime authority.
|
|
schemaVersion: 1
|
|
databases:
|
|
- workspaceId: CHANGE_ME
|
|
engine: postgres
|
|
databaseName: CHANGE_ME
|
|
schema: public
|
|
binding:
|
|
transport: postgres_direct
|
|
host: CHANGE_ME
|
|
port: 5432
|
|
username: CHANGE_ME
|
|
secretFiles:
|
|
password: %s
|
|
`, root("secrets/database-password"))
|
|
documents := map[string]string{
|
|
".gitignore": "*\n",
|
|
"thothii-installation.yaml": installation, "operator.env": environment,
|
|
"database-bootstrap.yaml": bootstrap,
|
|
"README.md": "# Preparation / Preparazione\n\nReplace every CHANGE_ME / Sostituire ogni CHANGE_ME. Keep all files outside workspace Git / Tenere tutti i file fuori dal Git dei workspace.\n\n1. Edit installation models, workspace remote and operator.env consistently. / Modificare modelli, remoto e operator.env in modo coerente.\n2. Add one database bootstrap entry for every workspace; use read-only DWH credentials in protected files. / Una voce database per workspace, credenziali DWH in sola lettura in file protetti.\n3. Run tht installation credentials --directory PATH before setup; fill provider/database secrets yourself. / Generare credenziali tecniche prima del setup; compilare i segreti esterni.\n4. Repeat tht --installation PATH/thothii-installation.yaml installation validate --workspaces WORKSPACES. / Correggere e ripetere.\n\nNo services, network calls or database writes / Nessun servizio, chiamata di rete o scrittura database.\n",
|
|
}
|
|
for _, name := range []string{".gitignore", "thothii-installation.yaml", "operator.env", "database-bootstrap.yaml", "README.md"} {
|
|
if err := safeio.WriteCanonicalNewPrivateFile(filepath.Join(directory, name), []byte(strings.TrimSpace(documents[name])+"\n"), 0o600); err != nil {
|
|
return fmt.Errorf("cannot create preparation files; inspect the new directory and retry in a new destination")
|
|
}
|
|
}
|
|
return nil
|
|
}
|