-
Notifications
You must be signed in to change notification settings - Fork 918
Improve terminal backup #2007
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Improve terminal backup #2007
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| /** | ||
| * Terminal backup page | ||
| * @param {() => void} onclose | ||
| */ | ||
| export default function TerminalBackup(onclose) { | ||
| import("./terminalBackup").then((res) => res.default(onclose)); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| import settingsPage from "components/settingsPage"; | ||
| import toast from "components/toast"; | ||
| import alert from "dialogs/alert"; | ||
| import loader from "dialogs/loader"; | ||
| import FileBrowser from "pages/fileBrowser"; | ||
| import helpers from "utils/helpers"; | ||
|
|
||
| export default function TerminalBackup(onclose) { | ||
| const backupSettings = { | ||
| alpineBase: true, | ||
| packages: true, | ||
| home: false, | ||
| public: false, | ||
| }; | ||
|
|
||
| const items = [ | ||
| { | ||
| key: "alpineBase", | ||
| text: "Alpine", | ||
| checkbox: backupSettings.alpineBase, | ||
| info: strings["alpineBase info"] || "Include Alpine environment", | ||
| }, | ||
| /*{ | ||
| key: "packages", | ||
| text: strings["packages"] || "Packages", | ||
| checkbox: backupSettings.packages, | ||
| info: strings["packages info"] || "Include installed packages", | ||
| },*/ | ||
| { | ||
| key: "home", | ||
| text: strings["home"] || "Home", | ||
| checkbox: backupSettings.home, | ||
| info: | ||
| strings["home info"] || | ||
| "Include Alpine /home /root and /public directory", | ||
| }, | ||
| { | ||
| key: "backup", | ||
| text: strings["backup"], | ||
| chevron: false, | ||
| info: "Create backup with selected components", | ||
| }, | ||
| ]; | ||
|
|
||
| const page = settingsPage(strings["backup"], items, callback, undefined, { | ||
| preserveOrder: true, | ||
| pageClassName: "detail-settings-page", | ||
| listClassName: "detail-settings-list", | ||
| infoAsDescription: true, | ||
| valueInTail: true, | ||
| }); | ||
|
|
||
| const oldHide = page.hide; | ||
| page.hide = () => { | ||
| oldHide(); | ||
| onclose?.(); | ||
| }; | ||
| page.show(); | ||
|
|
||
| function setPackagesTooltip() { | ||
| const packagesRow = document.querySelector('[data-key="packages"]'); | ||
| if (!packagesRow) return; | ||
| const input = packagesRow.querySelector(".input-checkbox input"); | ||
| if (input) { | ||
| input.disabled = !!backupSettings.alpineBase; | ||
| } | ||
| } | ||
|
Comment on lines
+60
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The packages settings item is disabled in the items array (wrapped in a block comment), so these helper functions will always have a Also, |
||
|
|
||
| function enforcePackageRule(value) { | ||
| if (backupSettings.alpineBase && value === false) { | ||
| toast( | ||
| strings["packages cannot be disabled when alpine base enabled"] || | ||
| "Packages cannot be disabled while Alpine base is enabled.", | ||
| ); | ||
| backupSettings.packages = true; | ||
| const pkgRow = document.querySelector('[data-key="packages"]'); | ||
| if (pkgRow) { | ||
| const checkbox = pkgRow.querySelector(".input-checkbox input"); | ||
| if (checkbox) checkbox.checked = true; | ||
| } | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| async function performBackup() { | ||
| try { | ||
| const { url } = await FileBrowser("folder", strings["select folder"]); | ||
|
|
||
| if (!url) return; | ||
|
|
||
| loader.showTitleLoader( | ||
| strings["creating backup"] || "Creating backup...", | ||
| ); | ||
|
|
||
| const backupPath = await Terminal.backup({ | ||
| alpineBase: backupSettings.alpineBase, | ||
| packages: backupSettings.packages, | ||
| home: backupSettings.home, | ||
| }); | ||
|
|
||
| await system.copyToUri( | ||
| backupPath, | ||
| url, | ||
| "aterm_backup.tar", | ||
| console.log, | ||
| console.error, | ||
| ); | ||
|
|
||
| loader.removeTitleLoader(); | ||
| alert( | ||
| strings.success.toUpperCase(), | ||
| `${strings["backup successful"] || "Backup successful"}.`, | ||
| ); | ||
| } catch (error) { | ||
| loader.removeTitleLoader(); | ||
| console.error("Terminal backup failed:", error); | ||
| toast(error.toString()); | ||
| } | ||
| } | ||
|
|
||
| function callback(key, value) { | ||
| switch (key) { | ||
| case "alpineBase": | ||
| backupSettings.alpineBase = value; | ||
| if (value) { | ||
| backupSettings.packages = true; | ||
| const pkgRow = document.querySelector('[data-key="packages"]'); | ||
| if (pkgRow) { | ||
| const checkbox = pkgRow.querySelector(".input-checkbox input"); | ||
| if (checkbox) checkbox.checked = true; | ||
| } | ||
| } | ||
| setPackagesTooltip(); | ||
| break; | ||
| case "packages": | ||
| if (enforcePackageRule(value)) return; | ||
| backupSettings.packages = value; | ||
| break; | ||
| case "home": | ||
| backupSettings.home = value; | ||
| break; | ||
| case "backup": | ||
| performBackup(); | ||
| return; | ||
| default: | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -62,7 +62,10 @@ ARGS="$ARGS -b /dev/urandom:/dev/random" | |
| ARGS="$ARGS -b /proc" | ||
| ARGS="$ARGS -b /sys" | ||
| ARGS="$ARGS -b $PREFIX" | ||
| #keeping /public for backward compatibility, as some users might be using it for storing files | ||
| ARGS="$ARGS -b $PREFIX/public:/public" | ||
| ARGS="$ARGS -b $PREFIX/public:/home" | ||
| ARGS="$ARGS -b $PREFIX/public:/root" | ||
|
Comment on lines
+67
to
+68
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Both Consider whether the intent is truly to unify these paths, and add a comment explaining the reasoning if so. |
||
| ARGS="$ARGS -b $PREFIX/alpine/tmp:/dev/shm" | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -321,25 +321,86 @@ const Terminal = { | |||||||||||||||
| * console.error(`Backup failed: ${error}`); | ||||||||||||||||
| * } | ||||||||||||||||
| */ | ||||||||||||||||
| backup() { | ||||||||||||||||
| backup(options = {}) { | ||||||||||||||||
| return new Promise(async (resolve, reject) => { | ||||||||||||||||
| if (!await this.isInstalled()) { | ||||||||||||||||
| reject("Alpine is not installed."); | ||||||||||||||||
| return; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| const opts = { | ||||||||||||||||
| alpineBase: true, | ||||||||||||||||
| packages: false, | ||||||||||||||||
| home: false, | ||||||||||||||||
| ...options, | ||||||||||||||||
| }; | ||||||||||||||||
|
|
||||||||||||||||
| const includeFiles = []; | ||||||||||||||||
| const excludePaths = [ | ||||||||||||||||
| "alpine/system", | ||||||||||||||||
| "alpine/vendor", | ||||||||||||||||
| "alpine/sdcard", | ||||||||||||||||
| "alpine/storage", | ||||||||||||||||
| "alpine/apex", | ||||||||||||||||
| "alpine/odm", | ||||||||||||||||
| "alpine/product", | ||||||||||||||||
| "alpine/system_ext", | ||||||||||||||||
| "alpine/linkerconfig", | ||||||||||||||||
| "alpine/proc", | ||||||||||||||||
| "alpine/sys", | ||||||||||||||||
| "alpine/dev", | ||||||||||||||||
| "alpine/run", | ||||||||||||||||
| "alpine/tmp", | ||||||||||||||||
| ]; | ||||||||||||||||
|
|
||||||||||||||||
| if (opts.alpineBase) { | ||||||||||||||||
| includeFiles.push("alpine", ".downloaded", ".extracted", ".configured", "axs"); | ||||||||||||||||
| if (opts.packages) { | ||||||||||||||||
| includeFiles.push("alpine/data"); | ||||||||||||||||
| excludePaths.splice(excludePaths.indexOf("alpine/data"), 1); | ||||||||||||||||
| } | ||||||||||||||||
|
Comment on lines
+358
to
+361
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The fix is to add
Suggested change
And add const excludePaths = [
"alpine/data", // <-- add this
"alpine/system",
...
"alpine/tmp",
]; |
||||||||||||||||
| if (opts.home) { | ||||||||||||||||
| const checkCmd = `test -e "$PREFIX/public" && echo "exists" || echo "not"`; | ||||||||||||||||
| const checkResult = await Executor.execute(checkCmd); | ||||||||||||||||
| if (checkResult === "exists") { | ||||||||||||||||
| includeFiles.push("public"); | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } else { | ||||||||||||||||
| // If alpineBase is disabled, only include public if home is enabled | ||||||||||||||||
| if (opts.home) { | ||||||||||||||||
| const checkCmd = `test -e "$PREFIX/public" && echo "exists" || echo "not"`; | ||||||||||||||||
| const checkResult = await Executor.execute(checkCmd); | ||||||||||||||||
| if (checkResult === "exists") { | ||||||||||||||||
| includeFiles.push("public"); | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| if (!includeFiles.length) { | ||||||||||||||||
| reject("No components selected for backup."); | ||||||||||||||||
| return; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| let excludeCmd = ""; | ||||||||||||||||
| excludePaths.forEach((path) => { | ||||||||||||||||
| excludeCmd += ` --exclude=${path}`; | ||||||||||||||||
| }); | ||||||||||||||||
|
|
||||||||||||||||
| const includeStr = includeFiles.join(" "); | ||||||||||||||||
| const cmd = ` | ||||||||||||||||
| set -e | ||||||||||||||||
| INCLUDE_FILES="alpine .downloaded .extracted .configured axs" | ||||||||||||||||
| INCLUDE_FILES="${includeStr}" | ||||||||||||||||
| if [ "$FDROID" = "true" ]; then | ||||||||||||||||
| INCLUDE_FILES="$INCLUDE_FILES libtalloc.so.2 libproot-xed.so" | ||||||||||||||||
| fi | ||||||||||||||||
| EXCLUDE="--exclude=alpine/data --exclude=alpine/system --exclude=alpine/vendor --exclude=alpine/sdcard --exclude=alpine/storage --exclude=alpine/public --exclude=alpine/apex --exclude=alpine/odm --exclude=alpine/product --exclude=alpine/system_ext --exclude=alpine/linkerconfig --exclude=alpine/proc --exclude=alpine/sys --exclude=alpine/dev --exclude=alpine/run --exclude=alpine/tmp" | ||||||||||||||||
| tar -cf "$PREFIX/aterm_backup.tar" -C "$PREFIX" $EXCLUDE $INCLUDE_FILES | ||||||||||||||||
| tar -cf "$PREFIX/aterm_backup.tar" -C "$PREFIX"${excludeCmd} $INCLUDE_FILES | ||||||||||||||||
| echo "ok" | ||||||||||||||||
| `; | ||||||||||||||||
|
|
||||||||||||||||
| const result = await Executor.execute(cmd); | ||||||||||||||||
| if (result === "ok") { | ||||||||||||||||
| resolve(cordova.file.dataDirectory + "aterm_backup.tar"); | ||||||||||||||||
| resolve(cordova.file.dataDirectory + "usr/aterm_backup.tar"); | ||||||||||||||||
| } else { | ||||||||||||||||
| reject(result); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
helpersis imported but never referenced anywhere in this file.(Remove the import entirely.)