Skip to content
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

chore: Fix typing in ctl backup and restore #37663

Merged
merged 4 commits into from
Nov 24, 2024
Merged

Conversation

sharat87
Copy link
Member

@sharat87 sharat87 commented Nov 23, 2024

Now that we've moved to TypeScript, this PR fixes missing type annotations in backup.ts and restore.ts.

Automation

/test sanity

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/11988138792
Commit: 5770dd0
Cypress dashboard.
Tags: @tag.Sanity
Spec:


Sun, 24 Nov 2024 01:02:33 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Enhanced error handling for password mismatches during backup encryption.
    • Improved test coverage for backup functionality, including backup paths and disk space validation.
  • Bug Fixes

    • Refined backup cleanup logic to ensure proper file retention and removal.
  • Refactor

    • Introduced a new BackupState class to manage backup process state.
    • Streamlined password handling and improved code structure for better readability.
    • Updated type safety for several functions in the backup and restore processes.
    • Simplified exit process in error handling for restore functionality.

Copy link
Contributor

coderabbitai bot commented Nov 23, 2024

Walkthrough

The changes in this pull request involve significant modifications to the backup functionality within the application. A new class, BackupState, has been introduced to encapsulate backup-related properties and methods. The getEncryptionPasswordFromUser function has been updated to throw an error for mismatched passwords, enhancing error handling. The test suite has been expanded to cover various scenarios, and several function signatures have been updated to include type annotations for improved type safety.

Changes

File Path Change Summary
app/client/packages/rts/src/ctl/backup.ts - Added class BackupState to manage backup state properties.
- Updated getEncryptionPasswordFromUser method to throw an error on password mismatch.
- Refactored the run function to utilize BackupState.
- Updated multiple function signatures to include type annotations for enhanced type safety.
app/client/packages/rts/src/ctl/backup.test.ts - Expanded test cases for backup functionality, including scenarios for backup paths, disk space validation, and sensitive data handling.
- Refined tests for backup cleanup logic and MongoDB command generation.
- Implemented mocks for filesystem operations and user input to ensure robust and isolated tests.
app/client/packages/rts/src/ctl/restore.ts - Added TypeScript type annotations to several asynchronous functions for enhanced type safety.
- Removed errorCode variable, simplifying error handling and exit processes.
- Updated function signatures to include parameter types for various restore functions.

Possibly related PRs

Suggested reviewers

  • nidhi-nair
  • pratapaprasanna
  • mohanarpit

🎉 In the realm of backups, a change so grand,
A BackupState class now takes a stand.
With passwords checked and errors thrown,
The tests now cover paths well-known.
Type safety shines, the code's refined,
In this backup world, peace of mind! 🌟

Warning

Rate limit exceeded

@sharat87 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 032df64 and 5770dd0.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sharat87 sharat87 changed the title Fix typing in ctl backup chore: Fix typing in ctl backup Nov 23, 2024
@github-actions github-actions bot added skip-changelog Adding this label to a PR prevents it from being listed in the changelog and removed skip-changelog Adding this label to a PR prevents it from being listed in the changelog labels Nov 23, 2024
@sharat87 sharat87 added the ok-to-test Required label for CI label Nov 23, 2024
@sharat87 sharat87 marked this pull request as ready for review November 23, 2024 14:37
@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Nov 23, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (6)
app/client/packages/rts/src/ctl/backup.test.ts (1)

234-234: Consider adding specific error message verification

The test correctly verifies that the function throws an error for mismatched passwords. However, it would be more robust to verify the specific error message to ensure the exact error condition is being tested.

-    expect(() => backup.getEncryptionPasswordFromUser()).toThrow();
+    expect(() => backup.getEncryptionPasswordFromUser()).toThrow("Passwords do not match");
app/client/packages/rts/src/ctl/backup.ts (5)

Line range hint 175-209: Avoid using synchronous readlineSync in asynchronous context

Using readlineSync for user input is synchronous and can block the event loop. Consider using an asynchronous alternative to improve performance and avoid blocking other operations.

Refactor the code to use an asynchronous method for reading user input:

- const encryptionPwd1: string = readlineSync.question(
-   "Enter a password to encrypt the backup archive: ",
-   { hideEchoBack: true },
- );
+ const encryptionPwd1: string = await utils.promptUser(
+   "Enter a password to encrypt the backup archive: ",
+   true,
+ );

Ensure that utils.promptUser is an asynchronous function that handles user input without blocking the event loop.


312-317: Rename executeCopyCMD to reflect its functionality

The function executeCopyCMD creates a symbolic link using ln -s, but the name suggests it performs a copy operation. Rename the function to better describe its action.

Apply this diff to rename the function:

-export async function executeCopyCMD(srcFolder: string, destFolder: string) {
+export async function createSymbolicLink(srcFolder: string, destFolder: string) {
  return await utils.execCommand([
    "ln",
    "-s",
    srcFolder,
    path.join(destFolder, "git-storage"),
  ]);
}

113-113: Assign process.exitCode in the finally block

Assigning process.exitCode = 1; in the catch block may not ensure that it's set before the process exits, due to asynchronous operations in the finally block. Move the assignment to the finally block to guarantee it is set correctly.

Apply this diff to move process.exitCode assignment:

 } catch (err) {
-  process.exitCode = 1;
   await logger.backup_error(err.stack);
   // ... existing code ...
 } finally {
+  if (err) {
+    process.exitCode = 1;
+  }
   // ... existing code ...
 }

357-358: Simplify getBackupArchiveLimit function

The function can be simplified using the nullish coalescing operator for better readability.

Apply this diff to simplify the function:

export function getBackupArchiveLimit(backupArchivesLimit?: number): number {
-  return backupArchivesLimit || Constants.APPSMITH_DEFAULT_BACKUP_ARCHIVE_LIMIT;
+  return backupArchivesLimit ?? Constants.APPSMITH_DEFAULT_BACKUP_ARCHIVE_LIMIT;
}

Line range hint 386-393: Improve error message clarity in checkAvailableBackupSpace

The error message could be more precise about the required disk space. Specify the exact amount needed for better user understanding.

Apply this diff to enhance the error message:

throw new Error(
-  "Not enough space available at /appsmith-stacks. Please ensure availability of at least 2GB to backup successfully.",
+  "Insufficient disk space at /appsmith-stacks. Please ensure at least 2GB of free space to perform a successful backup.",
);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 5c15017 and 9a24517.

📒 Files selected for processing (2)
  • app/client/packages/rts/src/ctl/backup.test.ts (1 hunks)
  • app/client/packages/rts/src/ctl/backup.ts (16 hunks)

app/client/packages/rts/src/ctl/backup.ts Outdated Show resolved Hide resolved
app/client/packages/rts/src/ctl/backup.ts Show resolved Hide resolved
app/client/packages/rts/src/ctl/backup.ts Show resolved Hide resolved
@sharat87 sharat87 changed the title chore: Fix typing in ctl backup chore: Fix typing in ctl backup and restore Nov 23, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (6)
app/client/packages/rts/src/ctl/restore.ts (6)

Line range hint 60-78: Add return type and extract magic number

The function signature could be improved for better type safety.

-async function decryptArchive(encryptedFilePath: string, backupFilePath: string) {
+const PBKDF2_ITERATIONS = 100000;
+async function decryptArchive(encryptedFilePath: string, backupFilePath: string): Promise<boolean> {
   // ...
   "-iter",
-  "100000",
+  PBKDF2_ITERATIONS.toString(),

96-96: Add explicit return type

For consistency with TypeScript best practices, add return type annotation.

-async function extractArchive(backupFilePath: string, restoreRootPath: string) {
+async function extractArchive(backupFilePath: string, restoreRootPath: string): Promise<void> {

Line range hint 108-138: Improve error handling in database restoration

The catch block suppresses specific error details which could be valuable for debugging.

  } catch (error) {
    console.warn(
-     "Error reading manifest file. Assuming same database name.",
+     `Error reading manifest file. Assuming same database name. Details: ${error instanceof Error ? error.message : 'Unknown error'}`,
      error
    );
  }

139-141: Consider splitting function and enhancing security

The function handles multiple responsibilities and sensitive data. Consider:

  1. Breaking it into smaller functions
  2. Clearing sensitive data from memory after use

Would you like me to provide a detailed refactoring suggestion?


230-230: Add error handling for git storage restoration

Consider adding try-catch block to handle potential file system operation failures.

-async function restoreGitStorageArchive(restoreContentsPath: string, backupName: string) {
+async function restoreGitStorageArchive(restoreContentsPath: string, backupName: string): Promise<void> {
   try {
     console.log("Restoring git-storage archive");
     // ... existing code ...
   } catch (error) {
     console.error("Failed to restore git storage:", error);
     throw error;
   }
}

384-386: Add input validation

Consider adding null/undefined check for more robust implementation.

-function isArchiveEncrypted(backupFilePath: string) {
+function isArchiveEncrypted(backupFilePath: string): boolean {
+  if (!backupFilePath) return false;
   return backupFilePath.endsWith(".enc");
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9a24517 and 032df64.

📒 Files selected for processing (1)
  • app/client/packages/rts/src/ctl/restore.ts (11 hunks)

app/client/packages/rts/src/ctl/restore.ts Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
app/client/packages/rts/src/ctl/backup.ts (2)

Line range hint 27-147: Consider breaking down the run function into smaller, focused functions

The run function is handling multiple responsibilities which makes it harder to maintain and test. Consider extracting the backup, encryption, and cleanup logic into separate functions.


312-317: Add error handling for symbolic link creation

The symbolic link creation could fail due to permissions or existing links. Consider adding specific error handling.

 export async function executeCopyCMD(srcFolder: string, destFolder: string) {
+  try {
     return await utils.execCommand([
       "ln",
       "-s",
       srcFolder,
       path.join(destFolder, "git-storage"),
     ]);
+  } catch (error) {
+    if (error.code === 'EEXIST') {
+      throw new Error(`Git storage directory already exists at ${destFolder}`);
+    }
+    throw error;
+  }
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 032df64 and 5770dd0.

📒 Files selected for processing (2)
  • app/client/packages/rts/src/ctl/backup.ts (16 hunks)
  • app/client/packages/rts/src/ctl/restore.ts (11 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/client/packages/rts/src/ctl/restore.ts
🔇 Additional comments (5)
app/client/packages/rts/src/ctl/backup.ts (5)

13-25: LGTM! Well-structured class implementation

The BackupState class is well-implemented with proper TypeScript types and initialization of all properties.


147-147: Remove process.exit() call

Using process.exit() in an async function can lead to unfinished operations. Let the process exit naturally after all operations complete.


Line range hint 151-209: Strong implementation of encryption-related functions

Good error handling and proper type annotations. The encryption password validation is thorough with appropriate retry logic.


Line range hint 321-364: Well-structured utility functions

Functions are focused, well-typed, and handle their responsibilities clearly.


Line range hint 378-392: LGTM! Proper disk space validation

The implementation correctly checks for available space with appropriate error handling.

app/client/packages/rts/src/ctl/backup.ts Show resolved Hide resolved
@sharat87 sharat87 merged commit 392524e into release Nov 24, 2024
45 checks passed
@sharat87 sharat87 deleted the chore/backup-typing branch November 24, 2024 04:02
github-actions bot pushed a commit to Zeral-Zhang/appsmith that referenced this pull request Nov 27, 2024
Now that we've moved to TypeScript, this PR fixes missing type
annotations in `backup.ts` and `restore.ts`.


## Automation

/test sanity

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/11988138792>
> Commit: 5770dd0
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=11988138792&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Sanity`
> Spec:
> <hr>Sun, 24 Nov 2024 01:02:33 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [x] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced error handling for password mismatches during backup
encryption.
- Improved test coverage for backup functionality, including backup
paths and disk space validation.

- **Bug Fixes**
- Refined backup cleanup logic to ensure proper file retention and
removal.

- **Refactor**
	- Introduced a new `BackupState` class to manage backup process state.
- Streamlined password handling and improved code structure for better
readability.
- Updated type safety for several functions in the backup and restore
processes.
	- Simplified exit process in error handling for restore functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants