frontends.rst 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. .. include:: ../global.rst.inc
  2. .. highlight:: json
  3. .. _json_output:
  4. All about JSON: How to develop frontends
  5. ========================================
  6. Borg does not have a public API on the Python level. That does not keep you from writing :code:`import borg`,
  7. but does mean that there are no release-to-release guarantees on what you might find in that package, not
  8. even for point releases (1.1.x), and there is no documentation beyond the code and the internals documents.
  9. Borg does on the other hand provide an API on a command-line level. In other words, a frontend should to
  10. (for example) create a backup archive just invoke :ref:`borg_create`.
  11. Logging
  12. -------
  13. Especially for graphical frontends it is important to be able to convey and reformat progress information
  14. in meaningful ways. The ``--log-json`` option turns the stderr stream of Borg into a stream of JSON lines,
  15. where each line is a JSON object. The *type* key of the object determines its other contents.
  16. Since JSON can only encode text, any string representing a file system path may miss non-text parts.
  17. The following types are in use. Progress information is governed by the usual rules for progress information,
  18. it is not produced unless ``--progress`` is specified.
  19. archive_progress
  20. Output during operations creating archives (:ref:`borg_create` and :ref:`borg_recreate`).
  21. The following keys exist, each represents the current progress.
  22. original_size
  23. Original size of data processed so far (before compression and deduplication)
  24. compressed_size
  25. Compressed size
  26. deduplicated_size
  27. Deduplicated size
  28. nfiles
  29. Number of (regular) files processed so far
  30. path
  31. Current path
  32. progress_message
  33. A message-based progress information with no concrete progress information, just a message
  34. saying what is currently being worked on.
  35. operation
  36. unique, opaque integer ID of the operation
  37. :ref:`msgid <msgid>`
  38. Message ID of the operation (may be *none*)
  39. finished
  40. boolean indicating whether the operation has finished, only the last object for an *operation*
  41. can have this property set to *true*.
  42. message
  43. current progress message (may be empty/absent)
  44. progress_percent
  45. Absolute progress information with defined end/total and current value.
  46. operation
  47. unique, opaque integer ID of the operation
  48. :ref:`msgid <msgid>`
  49. Message ID of the operation (may be *none*)
  50. finished
  51. boolean indicating whether the operation has finished, only the last object for an *operation*
  52. can have this property set to *true*.
  53. message
  54. A formatted progress message, this will include the percentage and perhaps other information
  55. current
  56. Current value (always less-or-equal to *total*)
  57. info
  58. Array that describes the current item, may be *none*, contents depend on *msgid*
  59. total
  60. Total value
  61. file_status
  62. This is only output by :ref:`borg_create` and :ref:`borg_recreate` if ``--list`` is specified. The usual
  63. rules for the file listing applies, including the ``--filter`` option.
  64. status
  65. Single-character status as for regular list output
  66. path
  67. Path of the file system object
  68. log_message
  69. Any regular log output invokes this type. Regular log options and filtering applies to these as well.
  70. created
  71. Unix timestamp (float)
  72. levelname
  73. Upper-case log level name (also called severity). Defined levels are: DEBUG, INFO, WARNING, ERROR, CRITICAL
  74. name
  75. Name of the emitting entity
  76. message
  77. Formatted log message
  78. :ref:`msgid <msgid>`
  79. Message ID, may be *none* or absent
  80. .. rubric:: Examples (reformatted, each object would be on exactly one line)
  81. :ref:`borg_extract` progress::
  82. {"message": "100.0% Extracting: src/borgbackup.egg-info/entry_points.txt",
  83. "current": 13000228, "total": 13004993, "info": ["src/borgbackup.egg-info/entry_points.txt"],
  84. "operation": 1, "msgid": "extract", "type": "progress_percent", "finished": false}
  85. {"message": "100.0% Extracting: src/borgbackup.egg-info/SOURCES.txt",
  86. "current": 13004993, "total": 13004993, "info": ["src/borgbackup.egg-info/SOURCES.txt"],
  87. "operation": 1, "msgid": "extract", "type": "progress_percent", "finished": false}
  88. {"operation": 1, "msgid": "extract", "type": "progress_percent", "finished": true}
  89. :ref:`borg_create` file listing with progress::
  90. {"original_size": 0, "compressed_size": 0, "deduplicated_size": 0, "nfiles": 0, "type": "archive_progress", "path": "src"}
  91. {"type": "file_status", "status": "U", "path": "src/borgbackup.egg-info/entry_points.txt"}
  92. {"type": "file_status", "status": "U", "path": "src/borgbackup.egg-info/SOURCES.txt"}
  93. {"type": "file_status", "status": "d", "path": "src/borgbackup.egg-info"}
  94. {"type": "file_status", "status": "d", "path": "src"}
  95. {"original_size": 13176040, "compressed_size": 11386863, "deduplicated_size": 503, "nfiles": 277, "type": "archive_progress", "path": ""}
  96. Internal transaction progress::
  97. {"message": "Saving files cache", "operation": 2, "msgid": "cache.commit", "type": "progress_message", "finished": false}
  98. {"message": "Saving cache config", "operation": 2, "msgid": "cache.commit", "type": "progress_message", "finished": false}
  99. {"message": "Saving chunks cache", "operation": 2, "msgid": "cache.commit", "type": "progress_message", "finished": false}
  100. {"operation": 2, "msgid": "cache.commit", "type": "progress_message", "finished": true}
  101. A debug log message::
  102. {"message": "35 self tests completed in 0.08 seconds",
  103. "type": "log_message", "created": 1488278449.5575905, "levelname": "DEBUG", "name": "borg.archiver"}
  104. Standard output
  105. ---------------
  106. *stdout* is different and more command-dependent. Commands like :ref:`borg_info`, :ref:`borg_create`
  107. and :ref:`borg_list` implement a ``--json`` option which turns their regular output into a single JSON object.
  108. Dates are formatted according to ISO-8601 with the strftime format string '%a, %Y-%m-%d %H:%M:%S',
  109. e.g. *Sat, 2016-02-25 23:50:06*.
  110. The root object at least contains a *repository* key with an object containing:
  111. id
  112. The ID of the repository, normally 64 hex characters
  113. location
  114. Canonicalized repository path, thus this may be different from what is specified on the command line
  115. last_modified
  116. Date when the repository was last modified by the Borg client
  117. The *encryption* key, if present, contains:
  118. mode
  119. Textual encryption mode name (same as :ref:`borg_init` ``--encryption`` names)
  120. keyfile
  121. Path to the local key file used for access. Depending on *mode* this key may be absent.
  122. The *cache* key, if present, contains:
  123. path
  124. Path to the local repository cache
  125. stats
  126. Object containing cache stats:
  127. total_chunks
  128. Number of chunks
  129. total_unique_chunks
  130. Number of unique chunks
  131. total_size
  132. Total uncompressed size of all chunks multiplied with their reference counts
  133. total_csize
  134. Total compressed and encrypted size of all chunks multiplied with their reference counts
  135. unique_size
  136. Uncompressed size of all chunks
  137. unique_csize
  138. Compressed and encrypted size of all chunks
  139. Example *borg info* output::
  140. {
  141. "cache": {
  142. "path": "/home/user/.cache/borg/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  143. "stats": {
  144. "total_chunks": 511533,
  145. "total_csize": 17948017540,
  146. "total_size": 22635749792,
  147. "total_unique_chunks": 54892,
  148. "unique_csize": 1920405405,
  149. "unique_size": 2449675468
  150. }
  151. },
  152. "encryption": {
  153. "mode": "repokey"
  154. },
  155. "repository": {
  156. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  157. "last_modified": "Mon, 2017-02-27 21:21:58",
  158. "location": "/home/user/testrepo"
  159. },
  160. "security_dir": "/home/user/.config/borg/security/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23"
  161. }
  162. .. rubric:: Archive formats
  163. :ref:`borg_info` uses an extended format for archives, which is more expensive to retrieve, while
  164. :ref:`borg_list` uses a simpler format that is faster to retrieve. Either return archives in an
  165. array under the *archives* key, while :ref:`borg_create` returns a single archive object under the
  166. *archive* key.
  167. Both formats contain a *name* key with the archive name, the *id* key with the hexadecimal archive ID,
  168. and the *start* key with the start timestamp.
  169. *borg info* and *borg create* further have:
  170. end
  171. End timestamp
  172. duration
  173. Duration in seconds between start and end in seconds (float)
  174. stats
  175. Archive statistics (freshly calculated, this is what makes "info" more expensive)
  176. original_size
  177. Size of files and metadata before compression
  178. compressed_size
  179. Size after compression
  180. deduplicated_size
  181. Deduplicated size (against the current repository, not when the archive was created)
  182. nfiles
  183. Number of regular files in the archive
  184. limits
  185. Object describing the utilization of Borg limits
  186. max_archive_size
  187. Float between 0 and 1 describing how large this archive is relative to the maximum size allowed by Borg
  188. command_line
  189. Array of strings of the command line that created the archive
  190. The note about paths from above applies here as well.
  191. :ref:`borg_info` further has:
  192. hostname
  193. Hostname of the creating host
  194. username
  195. Name of the creating user
  196. comment
  197. Archive comment, if any
  198. Example of a simple archive listing (``borg list --last 1 --json``)::
  199. {
  200. "archives": [
  201. {
  202. "id": "80cd07219ad725b3c5f665c1dcf119435c4dee1647a560ecac30f8d40221a46a",
  203. "name": "host-system-backup-2017-02-27",
  204. "start": "Mon, 2017-02-27 21:21:52"
  205. }
  206. ],
  207. "encryption": {
  208. "mode": "repokey"
  209. },
  210. "repository": {
  211. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  212. "last_modified": "Mon, 2017-02-27 21:21:58",
  213. "location": "/home/user/repository"
  214. }
  215. }
  216. The same archive with more information (``borg info --last 1 --json``)::
  217. {
  218. "archives": [
  219. {
  220. "command_line": [
  221. "/home/user/.local/bin/borg",
  222. "create",
  223. "/home/user/repository",
  224. "..."
  225. ],
  226. "comment": "",
  227. "duration": 5.641542,
  228. "end": "Mon, 2017-02-27 21:21:58",
  229. "hostname": "host",
  230. "id": "80cd07219ad725b3c5f665c1dcf119435c4dee1647a560ecac30f8d40221a46a",
  231. "limits": {
  232. "max_archive_size": 0.0001330855110409714
  233. },
  234. "name": "host-system-backup-2017-02-27",
  235. "start": "Mon, 2017-02-27 21:21:52",
  236. "stats": {
  237. "compressed_size": 1880961894,
  238. "deduplicated_size": 2791,
  239. "nfiles": 53669,
  240. "original_size": 2400471280
  241. },
  242. "username": "user"
  243. }
  244. ],
  245. "cache": {
  246. "path": "/home/user/.cache/borg/0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  247. "stats": {
  248. "total_chunks": 511533,
  249. "total_csize": 17948017540,
  250. "total_size": 22635749792,
  251. "total_unique_chunks": 54892,
  252. "unique_csize": 1920405405,
  253. "unique_size": 2449675468
  254. }
  255. },
  256. "encryption": {
  257. "mode": "repokey"
  258. },
  259. "repository": {
  260. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  261. "last_modified": "Mon, 2017-02-27 21:21:58",
  262. "location": "/home/user/repository"
  263. }
  264. }
  265. .. rubric:: File listings
  266. Listing the contents of an archive can produce *a lot* of JSON. Each item (file, directory, ...) is described
  267. by one object in the *items* array of the :ref:`borg_list` output. Refer to the *borg list* documentation for
  268. the available keys and their meaning.
  269. Example (excerpt)::
  270. {
  271. "encryption": {
  272. "mode": "repokey"
  273. },
  274. "repository": {
  275. "id": "0cbe6166b46627fd26b97f8831e2ca97584280a46714ef84d2b668daf8271a23",
  276. "last_modified": "Mon, 2017-02-27 21:21:58",
  277. "location": "/home/user/repository"
  278. },
  279. "items": [
  280. {
  281. "type": "d",
  282. "mode": "drwxr-xr-x",
  283. "user": "user",
  284. "group": "user",
  285. "uid": 1000,
  286. "gid": 1000,
  287. "path": "linux",
  288. "healthy": true,
  289. "source": "",
  290. "linktarget": "",
  291. "flags": null,
  292. "isomtime": "Sat, 2016-05-07 19:46:01",
  293. "size": 0
  294. }
  295. ]
  296. }
  297. .. _msgid:
  298. Message IDs
  299. -----------
  300. Message IDs are strings that essentially give a log message or operation a name, without actually using the
  301. full text, since texts change more frequently. Message IDs are unambiguous and reduce the need to parse
  302. log messages.
  303. Assigned message IDs are:
  304. .. See scripts/errorlist.py; this is slightly edited.
  305. Errors
  306. Archive.AlreadyExists
  307. Archive {} already exists
  308. Archive.DoesNotExist
  309. Archive {} does not exist
  310. Archive.IncompatibleFilesystemEncodingError
  311. Failed to encode filename "{}" into file system encoding "{}". Consider configuring the LANG environment variable.
  312. Cache.CacheInitAbortedError
  313. Cache initialization aborted
  314. Cache.EncryptionMethodMismatch
  315. Repository encryption method changed since last access, refusing to continue
  316. Cache.RepositoryAccessAborted
  317. Repository access aborted
  318. Cache.RepositoryIDNotUnique
  319. Cache is newer than repository - do you have multiple, independently updated repos with same ID?
  320. Cache.RepositoryReplay
  321. Cache is newer than repository - this is either an attack or unsafe (multiple repos with same ID)
  322. Buffer.MemoryLimitExceeded
  323. Requested buffer size {} is above the limit of {}.
  324. ExtensionModuleError
  325. The Borg binary extension modules do not seem to be properly installed
  326. IntegrityError
  327. Data integrity error: {}
  328. NoManifestError
  329. Repository has no manifest.
  330. PlaceholderError
  331. Formatting Error: "{}".format({}): {}({})
  332. KeyfileInvalidError
  333. Invalid key file for repository {} found in {}.
  334. KeyfileMismatchError
  335. Mismatch between repository {} and key file {}.
  336. KeyfileNotFoundError
  337. No key file for repository {} found in {}.
  338. PassphraseWrong
  339. passphrase supplied in BORG_PASSPHRASE is incorrect
  340. PasswordRetriesExceeded
  341. exceeded the maximum password retries
  342. RepoKeyNotFoundError
  343. No key entry found in the config of repository {}.
  344. UnsupportedManifestError
  345. Unsupported manifest envelope. A newer version is required to access this repository.
  346. UnsupportedPayloadError
  347. Unsupported payload type {}. A newer version is required to access this repository.
  348. NotABorgKeyFile
  349. This file is not a borg key backup, aborting.
  350. RepoIdMismatch
  351. This key backup seems to be for a different backup repository, aborting.
  352. UnencryptedRepo
  353. Keymanagement not available for unencrypted repositories.
  354. UnknownKeyType
  355. Keytype {0} is unknown.
  356. LockError
  357. Failed to acquire the lock {}.
  358. LockErrorT
  359. Failed to acquire the lock {}.
  360. ConnectionClosed
  361. Connection closed by remote host
  362. InvalidRPCMethod
  363. RPC method {} is not valid
  364. PathNotAllowed
  365. Repository path not allowed
  366. RemoteRepository.RPCServerOutdated
  367. Borg server is too old for {}. Required version {}
  368. UnexpectedRPCDataFormatFromClient
  369. Borg {}: Got unexpected RPC data format from client.
  370. UnexpectedRPCDataFormatFromServer
  371. Got unexpected RPC data format from server:
  372. {}
  373. Repository.AlreadyExists
  374. Repository {} already exists.
  375. Repository.CheckNeeded
  376. Inconsistency detected. Please run "borg check {}".
  377. Repository.DoesNotExist
  378. Repository {} does not exist.
  379. Repository.InsufficientFreeSpaceError
  380. Insufficient free space to complete transaction (required: {}, available: {}).
  381. Repository.InvalidRepository
  382. {} is not a valid repository. Check repo config.
  383. Repository.ObjectNotFound
  384. Object with key {} not found in repository {}.
  385. Operations
  386. - cache.begin_transaction
  387. - cache.commit
  388. - cache.sync
  389. *info* is one string element, the name of the archive currently synced.
  390. - repository.compact_segments
  391. - repository.replay_segments
  392. - repository.check_segments
  393. - check.verify_data
  394. - extract
  395. *info* is one string element, the name of the path currently extracted.
  396. - extract.permissions
  397. - archive.delete