otb-cloud secure encrypted backups
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

170 lines
5.2 KiB

cd /opt/otb_cloud || exit 1
echo "===== backups ====="
STAMP=$(date +%Y%m%d-%H%M%S)
cp app/models/schema.sql /home/def/backuphere/schema.sql.$STAMP.bak
cp app/auth/utils.py /home/def/backuphere/utils.py.$STAMP.bak
cp VERSION /home/def/backuphere/VERSION.$STAMP.bak 2>/dev/null || true
cp PROJECT_STATE.md /home/def/backuphere/PROJECT_STATE.md.$STAMP.bak 2>/dev/null || true
cp README.md /home/def/backuphere/README.md.$STAMP.bak 2>/dev/null || true
echo "===== extend schema ====="
cat >> app/models/schema.sql <<'EOF'
-- ===============================
-- v1.1.0-alpha1 VIDEO JOB SYSTEM
-- ===============================
CREATE TABLE IF NOT EXISTS video_jobs (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
tenant_id INT NOT NULL,
device_id INT NOT NULL,
source_file_id BIGINT NULL,
source_relative_path VARCHAR(1000) NOT NULL,
source_original_filename VARCHAR(255) NOT NULL,
requested_profile VARCHAR(50) NOT NULL,
requested_gpu_preference VARCHAR(20) NOT NULL DEFAULT 'auto',
assigned_processor VARCHAR(20) NULL,
status VARCHAR(50) NOT NULL DEFAULT 'queued',
progress_percent INT NOT NULL DEFAULT 0,
output_relative_path VARCHAR(1000) NULL,
output_file_id BIGINT NULL,
log_excerpt LONGTEXT NULL,
error_message LONGTEXT NULL,
gpu_seconds INT NOT NULL DEFAULT 0,
started_at DATETIME NULL,
completed_at DATETIME NULL,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
created_by_user_id INT NULL,
CONSTRAINT fk_video_jobs_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id),
CONSTRAINT fk_video_jobs_device FOREIGN KEY (device_id) REFERENCES devices(id)
);
CREATE TABLE IF NOT EXISTS tenant_usage_metrics (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
tenant_id INT NOT NULL,
storage_bytes_originals BIGINT NOT NULL DEFAULT 0,
storage_bytes_video BIGINT NOT NULL DEFAULT 0,
storage_bytes_archive BIGINT NOT NULL DEFAULT 0,
storage_bytes_lts BIGINT NOT NULL DEFAULT 0,
storage_bytes_total BIGINT NOT NULL DEFAULT 0,
gpu_seconds_intel BIGINT NOT NULL DEFAULT 0,
gpu_seconds_amd BIGINT NOT NULL DEFAULT 0,
gpu_seconds_cpu BIGINT NOT NULL DEFAULT 0,
completed_jobs INT NOT NULL DEFAULT 0,
failed_jobs INT NOT NULL DEFAULT 0,
accrued_storage_cost DECIMAL(12,2) NOT NULL DEFAULT 0.00,
accrued_gpu_cost DECIMAL(12,2) NOT NULL DEFAULT 0.00,
calculated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_metrics_tenant FOREIGN KEY (tenant_id) REFERENCES tenants(id)
);
EOF
echo "===== update device directory structure ====="
python3 <<'PY'
from pathlib import Path
p = Path("app/auth/utils.py")
txt = p.read_text()
old = """for subdir in ["originals", "derived", "exports", "deleted", "tmp"]:"""
new = """for subdir in ["originals", "video", "video-workshop", "archive", "lts", "derived", "exports", "deleted", "tmp"]:"""
if old not in txt:
raise SystemExit("PATCH FAIL: device dir block not found")
txt = txt.replace(old, new)
p.write_text(txt)
print("device directory structure updated")
PY
echo "===== create service scaffolding ====="
mkdir -p app/services
cat > app/services/video_jobs.py <<'EOF'
def create_job(db, tenant_id, device_id, source_path, filename, profile):
return {
"tenant_id": tenant_id,
"device_id": device_id,
"source_path": source_path,
"filename": filename,
"profile": profile,
"status": "queued"
}
EOF
cat > app/services/video_metrics.py <<'EOF'
def recalc_metrics(db, tenant_id):
# placeholder for v1.1.0
return {"ok": True}
EOF
cat > app/services/gpu_select.py <<'EOF'
def select_processor():
# v1.1.0 logic placeholder
return "intel"
EOF
cat > app/services/video_profiles.py <<'EOF'
PROFILES = {
"portrait_web": "portrait web encode",
"landscape_web": "landscape web encode",
"high_quality_cpu": "cpu encode",
"archive_only": "no processing"
}
EOF
cat > app/services/video_paths.py <<'EOF'
def device_paths(base):
return {
"originals": f"{base}/originals",
"video": f"{base}/video",
"video_workshop": f"{base}/video-workshop",
"archive": f"{base}/archive",
"lts": f"{base}/lts"
}
EOF
echo "===== create worker scaffold ====="
cat > app/services/video_worker.py <<'EOF'
import time
def run_worker():
print("video worker starting (stub)")
while True:
time.sleep(10)
EOF
echo "===== bump version ====="
echo "v1.1.0-alpha1" > VERSION
echo "===== update PROJECT_STATE.md ====="
cat >> PROJECT_STATE.md <<'EOF'
## v1.1.0-alpha1 — Video System Foundation
- Added video_jobs table (processing queue)
- Added tenant_usage_metrics table (dashboard metrics)
- Added video service scaffolding (jobs, metrics, gpu select, profiles)
- Extended device structure to include:
- video
- video-workshop
- archive
- lts
- Prepared system for background worker architecture
Next step:
- Build video worker processing engine
EOF
echo "===== update README.md ====="
sed -i '1i\
## v1.1.0-alpha1 — Video System Foundation\n- Introduced video job queue system\n- Introduced tenant usage metrics\n- Added video processing scaffolding\n- Prepared for GPU worker processing\n' README.md
echo "===== verify ====="
python3 -m py_compile app/auth/utils.py
echo "===== done ====="