Backup, esportazione e importazione
Tutto ciò che Control Center può copiare, cedere o adottare, e la forma esatta di ogni artefatto. Per creare davvero un backup, vedi Backup e ripristino; per capire perché la persistenza è suddivisa in questo modo, vedi Spazi di lavoro e isolamento.
Artefatti
Sezione intitolata “Artefatti”Esistono tre artefatti di copia del database, con ambiti e politiche di eliminazione diversi.
| Artefatto | Scritto da | Forma | Copre |
|---|---|---|---|
| Istantanea dell’installazione | server.backupNow |
Una directory con data e ora | Tutti i database dell’installazione |
| Backup dello spazio di lavoro | pipeline Workspace backup |
Directory con data e ora con un solo .db |
Il database di uno spazio di lavoro |
| Esportazione dello spazio di lavoro | workspace.export |
Un singolo file .db |
Il database di uno spazio di lavoro |
Tutti vengono scritti con VACUUM INTO di SQLite, che è sicuro su un database WAL in
uso: apre una transazione di lettura, produce una copia deframmentata e
transazionalmente coerente e non richiede mai di fermare il server.
Struttura dell’istantanea
Sezione intitolata “Struttura dell’istantanea”<dataDir>/backups/2026-07-28T09-12-33-000Z/ manifest.json global.db <workspaceId>/workspace.db one directory per workspaceLa struttura rispecchia esattamente la directory dei dati attiva, ed è ciò che rende il
ripristino di un’installazione una copia di ritorno anziché una traduzione. Il nome
della directory è la data e ora UTC con : e . sostituiti da -, quindi è sicuro
per i filesystem di Windows e si ordina cronologicamente come semplice stringa.
I backup pianificati degli spazi di lavoro vivono separatamente in
<dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db.
Non includono un manifest né global.db e non sono istantanee dell’installazione.
Il passaggio di conservazione della pipeline settimanale elimina solo i backup del
proprio spazio di lavoro più vecchi dell’età configurata (30 giorni per impostazione
predefinita); le istantanee dell’installazione create manualmente non vengono mai
ruotate da quel passaggio. server.listBackups elenca solo le istantanee
dell’installazione, comprese quelle incomplete.
manifest.json
Sezione intitolata “manifest.json”| Campo | Tipo | Significato |
|---|---|---|
version |
int | Versione del formato del manifest. Attualmente 1 |
created_at |
ISO-8601 UTC | Quando l’istantanea è stata scattata |
global.file |
stringa | Sempre global.db |
global.schema_version |
int | Versione dello schema di GlobalDatabase al momento dell’acquisizione |
global.bytes |
int | Dimensione del global.db scritto |
workspace_schema_version |
int | Versione dello schema di WorkspaceDatabase condivisa da ogni file di spazio di lavoro |
workspaces[] |
array | Una voce per ogni spazio di lavoro acquisito |
workspaces[].workspace_id |
stringa | Lo spazio di lavoro contenuto in questo file |
workspaces[].file |
stringa | Percorso relativo alla radice dell’istantanea, <workspaceId>/workspace.db |
workspaces[].bytes |
int | Dimensione di quel file |
skipped_workspaces[] |
array di stringhe | Spazi di lavoro che il backup non è riuscito ad acquisire |
Uno spazio di lavoro viene saltato quando è registrato ma non vi è mai stato scritto
nulla (quindi il file non esiste ancora), oppure quando il suo VACUUM INTO non è
riuscito. In entrambi i casi l’istantanea viene comunque completata e il manifest indica
ciò che manca.
Completezza
Sezione intitolata “Completezza”server.listBackups riporta un flag complete per ogni istantanea. È false quando il
manifest è assente o non analizzabile, quando global.db manca, o quando il manifest
nomina un file di spazio di lavoro che non è su disco.
Un’istantanea incompleta viene comunque elencata, perché un’istantanea che un operatore
non vede è un’istantanea che crede di avere. Quando il manifest non è leggibile,
l’elenco ripiega sulla struttura stessa e riporta tutti i file
<workspaceId>/workspace.db che trova: quelli restano adottabili singolarmente tramite
workspace.import, anche se l’istantanea nel suo complesso non può ripristinare
un’installazione.
Cosa non contiene un backup
Sezione intitolata “Cosa non contiene un backup”Entrambi gli artefatti sono solo database. La directory di uno spazio di lavoro contiene più del suo database, e niente del resto viaggia:
| Percorso | In un’istantanea? | In un’esportazione dello spazio di lavoro? |
|---|---|---|
global.db |
Sì | No |
<workspaceId>/workspace.db |
Sì | Sì (è proprio il file) |
<workspaceId>/blobs/ |
No | No |
<workspaceId>/skills/ |
No | No |
<workspaceId>/agents/ |
No | No |
<workspaceId>/chat_credentials/ |
No | No |
<workspaceId>/spaces/<spaceId>/ |
No | No |
<workspaceId>/pr_clones/ |
No | No |
secrets.json |
No | No |
models/ |
No | No |
meetings/<meetingId>/ |
No | No |
rigs/ |
No | No |
Una parte è usa e getta: spaces/ contiene worktree copy-on-write che vengono
riprovisionati dai repo, pr_clones/ è una cache, models/ viene riscaricato, rigs/
è stato della macchina. Una parte no: blobs/ contiene le immagini incollate a cui
puntano le righe del database, skills/ e agents/ contengono i file con cui viene
eseguito un agente, e secrets.json contiene ogni chiave di associazione, credenziale
di fornitore e impostazione SSO dell’installazione. Vedi
Backup e ripristino
per coprire il resto.
Operazioni
Sezione intitolata “Operazioni”Gli RPC di backup dell’installazione e l’esportazione/importazione degli spazi di lavoro
sono riservati ai fullClient: un telefono associato non può attivarli. Su un server
senza porta di backup cablata, come il server demo, sono del tutto assenti — non
rifiutati, ma strutturalmente mancanti.
| Operazione | Tipo | Ambito | Ruolo minimo | Argomenti | Restituisce |
|---|---|---|---|---|---|
server.backupNow |
mutazione | Installazione | proprietario dell’installazione | nessuno | {ok, path} |
server.listBackups |
lettura | Installazione | proprietario dell’installazione | nessuno | {backups: [...]} |
server.deleteBackup |
mutazione | Installazione | proprietario dell’installazione | name |
{ok} |
workspace.export |
lettura | Spazio di lavoro | admin |
nessuno | {ok, path} |
workspace.import |
mutazione | Spazio di lavoro | owner |
source_path |
{ok, workspace_id} |
workspace.delete |
mutazione | Installazione* | owner |
id |
riga di registro contrassegnata come eliminata |
workspace.deletenon ha ambito perché la riga che contrassegna vive nel registro globale; il suo handler verifica l’appartenenza del chiamante allo spazio di lavoro indicato e richiedeowner.
path in ogni risposta è un percorso sull’host del server.
Risposta di server.listBackups
Sezione intitolata “Risposta di server.listBackups”Dalla più recente, ordinate per nome della directory (che è la data e ora, quindi l’ordine vale anche per un’istantanea il cui manifest non è stato leggibile).
{ "backups": [ { "path": "/…/backups/2026-07-28T09-12-33-000Z", "name": "2026-07-28T09-12-33-000Z", "created_at": "2026-07-28T09:12:33.000Z", "bytes": 481203712, "complete": true, "workspaces": [ { "workspace_id": "w_9f2c…", "path": "/…/backups/2026-07-28T09-12-33-000Z/w_9f2c…/workspace.db", "bytes": 190840832 } ], "skipped_workspace_ids": [] } ]}created_at viene omesso quando il manifest non è stato leggibile. bytes al livello
superiore è la dimensione reale su disco dell’intera directory, non la somma del
manifest: la domanda che si pone un operatore che ripulisce le istantanee è quanto costa
la directory, non quanto il backup intendeva scrivere.
Ogni workspaces[].path è esattamente ciò che workspace.import accetta come
source_path. È deliberato: «ripristina questo spazio di lavoro da questa istantanea»
è l’operazione di importazione, quindi le due non possono divergere in trattamenti
diversi dello stesso file.
Convalida di workspace.import
Sezione intitolata “Convalida di workspace.import”Prima che qualsiasi cosa venga sostituita, il file candidato viene aperto in sola
lettura con una connessione SQLite grezza di breve durata e viene letta la sua riga
workspace_meta.
| Condizione | Risultato |
|---|---|
Non è un database SQLite leggibile, o manca workspace_meta |
Rifiutato. Non viene toccato nulla |
| Id di spazio di lavoro registrato ≠ quello di destinazione | Consentito, registrato nei log. È così che uno spazio di lavoro viene duplicato o ripristinato sotto un nuovo id |
| Id dell’installazione registrato ≠ quello di questa installazione | Consentito, registrato nei log. I suoi dispositivi associati e gli id utente appartengono a quell’installazione e non si risolveranno qui |
| Id di spazio di lavoro non valido, o file inesistente | Rifiutato |
In caso di accettazione, il database dello spazio di lavoro di destinazione viene chiuso
e rimosso dal manager prima che il file vi venga copiato sopra (una connessione drift
aperta tiene il file e il suo -wal), poi riaperto così che beforeOpen reinstalli i
trigger FTS e di sincronizzazione, e gli indici FTS vengono ricostruiti: le tabelle dei
contenuti di un file importato sono popolate, ma il suo indice può essere obsoleto.
Route di trasferimento
Sezione intitolata “Route di trasferimento”Ogni operazione qui sopra parla in termini di percorsi lato server, il che è una
risposta completa solo quando il server è la tua macchina. Queste tre trasportano i
byte, sullo stesso canale firmato con PSK che usano il proxy dei media e il blob store.
Il chiamante firma una stringa di destinazione con la chiave pre-condivisa del suo
dispositivo e passa la firma come s.
| Route | Metodo | Query | Destinazione firmata | Richiede |
|---|---|---|---|---|
/backup/workspace |
GET | w, d, s |
backup-workspace:<workspaceId> |
admin dello spazio di lavoro |
/backup/snapshot |
GET | n, d, s |
backup-snapshot:<name> |
proprietario dell’installazione |
/backup/restore |
POST | w, d, s |
backup-restore:<workspaceId> |
proprietario dello spazio di lavoro |
w è un id di spazio di lavoro, n un nome di directory di istantanea, d l’id del
dispositivo chiamante, s la firma. n viene risolto rispetto all’elenco dei backup
anziché concatenato alla radice dei backup, quindi la route non può essere puntata su
una directory che l’elenco non avrebbe mostrato.
| Stato | Causa |
|---|---|
400 |
Manca un parametro di query obbligatorio, o il corpo di un caricamento è vuoto |
403 |
Dispositivo sconosciuto o revocato, firma non valida, o il chiamante non ha il ruolo |
404 |
Nessuna porta di backup su questo host, o il file di istantanea/spazio di lavoro indicato non esiste |
405 |
/backup/restore chiamato con un metodo diverso da POST |
413 |
Il corpo del caricamento supera gli 8 GiB, per content-length dichiarato o per byte effettivamente letti |
500 |
L’esportazione o l’archiviazione non è riuscita lato server |
Entrambi i download rispondono con Cache-Control: no-store e Accept-Ranges: none.
Ogni richiesta genera una copia nuova e la elimina dopo averla trasmessa in
streaming, quindi una risposta in cache o ripresa unirebbe i byte di due esportazioni
diverse in un unico file che sembra valido e non lo è.
/backup/snapshot restituisce <name>.zip, con voci relative alla radice
dell’istantanea, così l’estrazione riproduce manifest.json + global.db +
<workspaceId>/workspace.db. Le voci vengono scritte in ordine, quindi due archivi
della stessa istantanea sono lo stesso archivio.
/backup/restore trasmette il corpo direttamente in un file temporaneo anziché
bufferizzarlo, lo limita prima e durante la lettura, ed elimina il file temporaneo su
ogni percorso di uscita, compreso un rifiuto.
Percorsi e limiti
Sezione intitolata “Percorsi e limiti”| Elemento | Valore |
|---|---|
| Istantanee | <dataDir>/backups/<timestamp>/ |
| Backup pianificati degli spazi di lavoro | <dataDir>/backups/workspace-backups/<workspaceId>/<timestamp>/workspace.db |
| Esportazioni degli spazi di lavoro | <dataDir>/backups/exports/<workspaceId>-<timestamp>.db |
| Staging dei trasferimenti | <dataDir>/backups/transfer/ — un banco di lavoro, ripulito dalla route che lo scrive |
| Nome dell’archivio dell’istantanea | <snapshot directory name>.zip |
| Limite di caricamento | 8 GiB per POST /backup/restore |
| Conservazione | Istantanee dell’installazione: eliminazione manuale. Backup degli spazi di lavoro: pipeline settimanale, 30 giorni per impostazione predefinita |
Le directory exports/, transfer/ e workspace-backups/ non sono istantanee
dell’installazione e sono escluse da server.listBackups. Solo l’ultima directory ha
una conservazione pianificata; l’eliminazione di un’istantanea dell’installazione
richiede l’azione esplicita del proprietario dell’installazione.
Vedi anche
Sezione intitolata “Vedi anche”- Backup e ripristino — le procedure a cui appartengono queste operazioni
- Spazi di lavoro e isolamento — perché uno spazio di lavoro è un solo file
- CLI di
cc_server— la directory dei dati in cui si trovano questi percorsi - Mappa delle route — dove vive l’interfaccia
- Architettura — la separazione client/server che i percorsi seguono