pgjishnu30 commited on
Commit
6f91c8f
Β·
1 Parent(s): 3edd084

fix: add write-access test at startup + pipe sync logs to Space stdout

Browse files

- _test_write(): uploads .sync-ok sentinel on every startup, logs
clearly if the token lacks write permission
- entrypoint.sh: pipe sync daemon through tee so errors appear in
Space runtime logs (not just hidden /data/logs/sync.log)
- Sync commit errors now logged with full detail per cycle

Files changed (2) hide show
  1. entrypoint.sh +3 -2
  2. sync_engine.py +29 -0
entrypoint.sh CHANGED
@@ -173,8 +173,9 @@ python3 /cleaner.py &
173
  # The AI and terminal always work on the local filesystem β€” sync is
174
  # purely a background backup layer and never blocks any operation.
175
  echo "[SYNC] Starting background sync daemon..."
176
- python3 /sync_engine.py watch >> /data/logs/sync.log 2>&1 &
177
- echo "[SYNC] Sync daemon started (PID $!). Logs: /data/logs/sync.log"
 
178
 
179
  # ─── Ensure project dir exists ───────────────────────────────────────
180
  mkdir -p /projects/default
 
173
  # The AI and terminal always work on the local filesystem β€” sync is
174
  # purely a background backup layer and never blocks any operation.
175
  echo "[SYNC] Starting background sync daemon..."
176
+ # tee so sync errors appear in Space logs AND are saved to file
177
+ python3 /sync_engine.py watch 2>&1 | tee -a /data/logs/sync.log &
178
+ echo "[SYNC] Sync daemon started. Logs: /data/logs/sync.log"
179
 
180
  # ─── Ensure project dir exists ───────────────────────────────────────
181
  mkdir -p /projects/default
sync_engine.py CHANGED
@@ -155,6 +155,32 @@ class SyncEngine:
155
  )
156
  return False
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  def restore(self) -> None:
159
  """Download the entire dataset snapshot and restore local dirs."""
160
  if not self._api:
@@ -165,6 +191,9 @@ class SyncEngine:
165
  log.warning("Skipping restore β€” dataset repo not accessible")
166
  return
167
 
 
 
 
168
  log.info(f"=== RESTORE: pulling {HF_DATASET} ===")
169
  try:
170
  from huggingface_hub import snapshot_download
 
155
  )
156
  return False
157
 
158
+ def _test_write(self) -> bool:
159
+ """Upload a tiny sentinel file to verify write access. Logs clearly on failure."""
160
+ try:
161
+ from huggingface_hub import CommitOperationAdd
162
+ import io
163
+ self._api.create_commit(
164
+ repo_id=HF_DATASET,
165
+ repo_type="dataset",
166
+ commit_message="sync: write-access test",
167
+ operations=[CommitOperationAdd(
168
+ path_in_repo=".sync-ok",
169
+ path_or_fileobj=io.BytesIO(b"ok"),
170
+ )],
171
+ )
172
+ log.info("βœ… Write access confirmed β€” dataset sync is active")
173
+ return True
174
+ except Exception as exc:
175
+ log.error("=" * 60)
176
+ log.error("❌ SYNC WRITE FAILED β€” files will NOT be saved to dataset")
177
+ log.error(f" Error: {exc}")
178
+ log.error(" Fix: go to https://huggingface.co/settings/tokens")
179
+ log.error(" Create a token with 'Write' scope (not Read-only).")
180
+ log.error(" Then update HF_TOKEN in Space Settings β†’ Secrets.")
181
+ log.error("=" * 60)
182
+ return False
183
+
184
  def restore(self) -> None:
185
  """Download the entire dataset snapshot and restore local dirs."""
186
  if not self._api:
 
191
  log.warning("Skipping restore β€” dataset repo not accessible")
192
  return
193
 
194
+ # Verify write access immediately so errors are visible in Space logs
195
+ self._test_write()
196
+
197
  log.info(f"=== RESTORE: pulling {HF_DATASET} ===")
198
  try:
199
  from huggingface_hub import snapshot_download