Commit Graph

532 Commits

Author SHA1 Message Date
Girish Ramakrishnan f499c9ada9 integrity: add eventlog status for historic checks 2026-02-15 23:40:23 +01:00
Girish Ramakrishnan c1a73aa62a integrity: just clear last info on a (re)start
this way if a user stops it midway, the old info is cleared
2026-02-15 23:26:06 +01:00
Girish Ramakrishnan 601e787500 rsync: fix integrity check 2026-02-15 23:17:23 +01:00
Girish Ramakrishnan 9f2eefcbb3 embed integrity check task in backup API responses
The UI is polling for the taskId, might as well attach it
2026-02-15 14:11:56 +01:00
Girish Ramakrishnan fc2e39f41b Rename getByIdentifierAndStatePaged to listByIdentifierAndStatePaged 2026-02-15 12:22:43 +01:00
Girish Ramakrishnan 36aa641cb9 migrate to "export default"
also, set no-use-before-define in linter
2026-02-14 15:43:24 +01:00
Girish Ramakrishnan 96dc79cfe6 Migrate codebase from CommonJS to ES Modules
- Convert all require()/module.exports to import/export across 260+ files
- Add "type": "module" to package.json to enable ESM by default
- Add migrations/package.json with "type": "commonjs" to keep db-migrate compatible
- Convert eslint.config.js to ESM with sourceType: "module"
- Replace __dirname/__filename with import.meta.dirname/import.meta.filename
- Replace require.main === module with process.argv[1] === import.meta.filename
- Remove 'use strict' directives (implicit in ESM)
- Convert dynamic require() in switch statements to static import lookup maps
  (dns.js, domains.js, backupformats.js, backupsites.js, network.js)
- Extract self-referencing exports.CONSTANT patterns into standalone const
  declarations (apps.js, services.js, locks.js, users.js, mail.js, etc.)
- Lazify SERVICES object in services.js to avoid circular dependency TDZ issues
- Add clearMailQueue() to mailer.js for ESM-safe queue clearing in tests
- Add _setMockApp() to ldapserver.js for ESM-safe test mocking
- Add _setMockResolve() wrapper to dig.js for ESM-safe DNS mocking in tests
- Convert backupupload.js to use dynamic imports so --check exits before
  loading the module graph (which requires BOX_ENV)
- Update check-install to use ESM import for infra_version.js
- Convert scripts/ (hotfix, release, remote_hotfix.js, find-unused-translations)
- All 1315 tests passing

Migration stats (AI-assisted using Cursor with Claude):
- Wall clock time: ~3-4 hours
- Assistant completions: ~80-100
- Estimated token usage: ~1-2M tokens

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-14 15:11:45 +01:00
Girish Ramakrishnan 93a0063941 backups: add stop_integrity_check route 2026-02-09 22:00:40 +01:00
Girish Ramakrishnan 5276321ade integrity: add integrity check fields and initial UI 2026-02-08 23:26:57 +01:00
Girish Ramakrishnan fb04f78112 backupcleaner: fix listing of backups by site 2025-10-21 13:56:08 +02:00
Girish Ramakrishnan 07732310c1 backuptask: track copy and upload statistics 2025-10-20 14:09:12 +02:00
Girish Ramakrishnan 43e426ab9f Revert "Add no-use-before-define linter rule"
This reverts commit fdcc5d68a2.

Unfortunately, this requires us to move exports to the bottom.
This in turn causes circular dep issues and also access of
exports.GLOBAL_VAR in the global context
2025-10-08 21:17:52 +02:00
Girish Ramakrishnan ddb7551b92 integrity: store signature as base64 2025-10-07 18:42:51 +02:00
Girish Ramakrishnan 6ac914904e backups: make listing by site only return box backups 2025-10-07 12:13:14 +02:00
Girish Ramakrishnan 68dd1fbedb rename function to listByTypePaged 2025-10-07 12:07:46 +02:00
Girish Ramakrishnan 43962c4a5a add route to list backups by site 2025-10-06 14:52:29 +02:00
Girish Ramakrishnan 5dd5a20fc1 code -> sqlCode 2025-09-29 12:18:26 +02:00
Girish Ramakrishnan c5b7264f1a rename backupTargets to backupSites 2025-09-12 10:32:37 +02:00
Girish Ramakrishnan 19682ec21b tgz: integrity check 2025-08-15 21:23:39 +05:30
Girish Ramakrishnan 12e073e8cf use node: prefix for requires
mostly because code is being autogenerated by all the AI stuff using
this prefix. it's also used in the stack trace.
2025-08-14 12:55:35 +05:30
Girish Ramakrishnan 39cad02e0d backup: add a dummy removePrivateFields 2025-08-13 19:56:21 +05:30
Girish Ramakrishnan 0c79dcdf1b tgz: add fileCount to integrity 2025-08-13 19:56:21 +05:30
Girish Ramakrishnan 2e16dd983f backups: stash the stats to the backups table 2025-08-12 20:21:54 +05:30
Girish Ramakrishnan 47fc9561ab backups (tgz): save integrity information
we generate a signing key pair for each target. Initially, I had this
as global. We needed a route to return the public key and putting it
under backup target seemed natural. Since we delete the backups when
we delete a target, we lose all the signing hashes. So, it's fine to lose
the key pair on target delete.
2025-08-12 19:00:29 +05:30
Girish Ramakrishnan a0792aa469 backups: make sure reused error backup is in same target 2025-07-25 14:06:35 +02:00
Girish Ramakrishnan 59aaabecc7 backups: the get route was accidentally removed 2025-07-25 11:56:31 +02:00
Girish Ramakrishnan 276db17f0c backups: use a real targetId 2025-07-25 08:12:27 +02:00
Girish Ramakrishnan 62017b3ff5 backup: rename back backuplisting.js to backups.js
this was a transitional rename till I figured out how to split
it in backuptargets.js
2025-07-25 01:37:19 +02:00
Girish Ramakrishnan 931311f11f rename backups to backuptargets 2025-07-24 18:54:10 +02:00
Girish Ramakrishnan 5e456f378b backups: split listing and targets 2025-07-24 18:21:48 +02:00
Girish Ramakrishnan bf315258c5 backups: add target foreign key to backups table
format is part of the backup target

in the future, if we want per-app format or schedule, we can add this
separately to the apps table itself. the full box backup can ignore
apps with a set backup target and use the latest backup (like an errored app).
the nice thing is restore will work correctly.
2025-07-24 17:32:16 +02:00
Girish Ramakrishnan 9780db6fa0 add backup targets table 2025-07-24 17:32:16 +02:00
Girish Ramakrishnan 0aca6c2588 locks: rename lock types to make it clearer 2025-07-18 13:40:15 +02:00
Girish Ramakrishnan d9c104613c tasks: rework the startTask API
it is now async. change was required to reset the pending flag
2025-06-17 19:32:46 +02:00
Girish Ramakrishnan dd5e4adc73 replace underscore with our own
we only need like 5 simple functions
2025-02-13 14:14:34 +01:00
Girish Ramakrishnan 8c28871b76 typo 2024-12-14 23:25:14 +01:00
Girish Ramakrishnan 41bc08a07e backup: move appConfig to backups table
this is useful for clone also to copy notes, operators, checklist
of the time when the backup was made (as opposed to current)

at this point, it's not clear why we need a archives table. it's
an optimization to not have to store icon for every backup.
2024-12-10 21:04:37 +01:00
Girish Ramakrishnan 490840b71d archives: use separate table
Cleaner to separate things from the backups table.

* icon, appConfig, appStoreIcon etc are only valid for archives
* older version cloudron does not have appConfig in backups table (so it
  cannot be an archive entry)
2024-12-10 10:36:44 +01:00
Girish Ramakrishnan 2ad93c114e archive: add appConfig, icon and appStoreIcon 2024-12-09 23:25:31 +01:00
Girish Ramakrishnan 9200e6fc63 add archives api 2024-12-09 22:39:28 +01:00
Girish Ramakrishnan 710bd270d7 apps: add archive action 2024-12-09 18:51:49 +01:00
Girish Ramakrishnan 147e014205 backup: add archive flag 2024-12-09 16:25:31 +01:00
Girish Ramakrishnan 65a7f5f1c6 Use subarray instead of slice
says it's deprecated
2024-12-09 16:14:49 +01:00
Girish Ramakrishnan bb392207ea remove global lock
Currently, the update/apptask/fullbackup/platformstart take a
global lock and cannot run in parallel. This causes situations
where when a user tries to trigger an apptask, it says "waiting for
backup to finish..." etc

The solution is to let them run in parallel. We need a lock at the
app level as app operations running in parallel would be bad (tm).
In addition, the update task needs a lock just for the update part.
We also need multi-process locks. Running tasks as processes is core
to our "kill" strategy.

Various inter process locks were explored:

* node's IPC mechanism with process.send(). But this only works for direct node.js
children. taskworker is run via sudo and the IPC does not work.

* File lock using O_EXCL. Basic ideas to create lock files. While file creation
can be done atomically, it becomes complicated to clean up lock files when
the tasks crash. We need a way to know what locks were held by the crashing task.
flock and friends are not built-into node.js

* sqlite/redis were options but introduce additional deps

* Settled on MySQL based locking. Initial plan was to have row locks
or table locks. Each row is a kind of lock. While implementing, it was found that
we need many types of locks (and not just update lock and app locks). For example,
we need locks for each task type, so that only one task type is active at a time.

* Instead of rows, we can just lock table and have a json blob in it. This hit a road
block that LOCK TABLE is per session and our db layer cannot handle this easily! i.e
when issing two db.query() it might use two different connections from the pool. We have to
expose the connection, release connection etc.

* Next idea was atomic blob update of the blob checking if old blob was same. This approach,
was finally refined into a version field.

Phew!
2024-12-07 20:41:22 +01:00
Girish Ramakrishnan 6742cdf373 backups: remount remote if not mounted before a backup 2024-09-09 18:15:49 +02:00
Girish Ramakrishnan ea72cef7f9 storage: remove getProviderStatus 2024-09-09 17:36:51 +02:00
Girish Ramakrishnan d5ea99603f backups: give is a low oomScoreAdjust to not get killed 2024-07-19 13:05:09 +02:00
Girish Ramakrishnan d9b478cf1f rename setupStorage to setupManagedStorage 2024-06-25 13:06:40 +02:00
Girish Ramakrishnan 5852fac71a backups: validate mountOptions is an object for managed providers 2024-06-11 14:40:54 +02:00
Girish Ramakrishnan 00f6ef7603 backups: cannot change config in demo mode 2024-06-06 11:32:15 +02:00