Skip to content

Conversation

@jackyalbo
Copy link
Contributor

@jackyalbo jackyalbo commented Aug 10, 2025

Describe the Problem

We used to throw an error when trying to upgrade to the same version - Now we will just a regular response with "NoUpgradeRequired"

Issues: Fixed #xxx / Gap #xxx

  1. Fixed https://issues.redhat.com/browse/DFBUGS-2801

Testing Instructions:

  • Doc added/updated
  • Tests added

Summary by CodeRabbit

  • New Features

    • Added a new response indicating when a configuration directory upgrade is not required.
  • Bug Fixes

    • Improved upgrade behavior to return a clear response when no upgrade is needed, instead of treating it as an error.
  • Tests

    • Updated integration and unit tests to reflect the new "NoUpgradeRequired" response and improved test formatting for readability.

Signed-off-by: jackyalbo <jacky.albo@gmail.com>
@coderabbitai
Copy link

coderabbitai bot commented Aug 10, 2025

Walkthrough

A new response code NoUpgradeRequired was added to the CLI response constants. The upgrade logic in nc_upgrade_manager.js and CLI output in upgrade.js were updated to return this new code and a message when no upgrade is needed. Related integration and unit tests were updated to expect and assert this new behavior and response format.

Changes

Cohort / File(s) Change Summary
CLI Response Constants
src/manage_nsfs/manage_nsfs_cli_responses.js
Added ManageCLIResponse.NoUpgradeRequired constant with specific code, message, and status for scenarios where a config directory upgrade is not required.
Upgrade Logic
src/upgrade/nc_upgrade_manager.js
Modified upgrade_config_dir to return the new NoUpgradeRequired response instead of throwing an error when no upgrade is needed. Adjusted log level and return value structure. Minor JSDoc formatting fix.
Upgrade CLI Output
src/manage_nsfs/upgrade.js
Changed start_config_dir_upgrade to output a dynamic response code (upgrade_res.code if present, otherwise default) and only include upgrade_info in the response data.
Integration Tests
src/test/integration_tests/nc/cli/test_cli_upgrade.test.js
Reformatted test data for readability. Updated test for "no upgrade required" to expect the new response code and structure, parsing the CLI result differently and asserting on the new message and code.
Unit Tests
src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js
Reformatted imports and object literals for consistency. Updated test for "no upgrade required" to expect a resolved value with a detail message instead of a rejected error. Adjusted assertion helpers for formatting and destructuring.

Sequence Diagram(s)

sequenceDiagram
    participant CLI
    participant UpgradeManager
    participant ManageCLIResponse

    CLI->>UpgradeManager: start_config_dir_upgrade()
    UpgradeManager->>UpgradeManager: Check config dir versions
    alt Versions match (no upgrade needed)
        UpgradeManager->>ManageCLIResponse: Get NoUpgradeRequired
        UpgradeManager-->>CLI: { code: NoUpgradeRequired, upgrade_info: { detail: ... } }
    else Versions differ (upgrade needed)
        UpgradeManager->>UpgradeManager: Perform upgrade
        UpgradeManager-->>CLI: { code: UpgradeSuccessful, upgrade_info: ... }
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Note

🔌 MCP (Model Context Protocol) integration is now available in Early Access!

Pro users can now connect to remote MCP servers under the Integrations page to get reviews and chat conversations that understand additional development context.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.
    • Explain this complex logic.
    • 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 explain this code block.
  • 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 explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this 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.

Copy link

@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: 4

🧹 Nitpick comments (2)
src/test/integration_tests/nc/cli/test_cli_upgrade.test.js (1)

369-372: Assert NoUpgradeRequired (LGTM) — consider normalizing exec_manage_cli parsing

The new assertions match the updated behavior. Consider unifying result parsing across tests (res vs res.stdout) to reduce confusion, unless exec_manage_cli intentionally returns different shapes for success vs error.

src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js (1)

366-368: Clarify invalid host shape in test

Using an empty array for the host object works to produce undefined current_version, but it’s atypical and can hide structure issues. Prefer an empty object to keep schema clear.

-            const system_data = {
-                [hostname]: []
-            };
+            const system_data = {
+                [hostname]: {}
+            };
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 828d450 and 7458fab.

📒 Files selected for processing (5)
  • src/manage_nsfs/manage_nsfs_cli_responses.js (1 hunks)
  • src/manage_nsfs/upgrade.js (1 hunks)
  • src/test/integration_tests/nc/cli/test_cli_upgrade.test.js (5 hunks)
  • src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js (12 hunks)
  • src/upgrade/nc_upgrade_manager.js (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit Configuration File

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js
  • src/test/integration_tests/nc/cli/test_cli_upgrade.test.js
🧬 Code Graph Analysis (3)
src/manage_nsfs/manage_nsfs_cli_responses.js (3)
src/cmd/manage_nsfs.js (1)
  • ManageCLIResponse (28-28)
src/manage_nsfs/diagnose.js (1)
  • ManageCLIResponse (12-12)
src/manage_nsfs/manage_nsfs_logging.js (1)
  • ManageCLIResponse (10-10)
src/manage_nsfs/upgrade.js (1)
src/cmd/manage_nsfs.js (1)
  • ManageCLIResponse (28-28)
src/test/integration_tests/nc/cli/test_cli_upgrade.test.js (2)
src/upgrade/nc_upgrade_manager.js (1)
  • hostname (14-14)
src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js (1)
  • hostname (34-34)
🔇 Additional comments (20)
src/manage_nsfs/manage_nsfs_cli_responses.js (1)

157-161: Add NoUpgradeRequired response (LGTM) — confirm event mapping intent

Constant is well-formed and consistent with existing responses. Please confirm that emitting no “success” event for this scenario is intentional (it’s not mapped in NSFS_CLI_SUCCESS_EVENT_MAP). If you do want an event, consider adding a distinct mapping and event type.

src/upgrade/nc_upgrade_manager.js (2)

12-12: Import ManageCLIResponse (LGTM)

Needed for the new response code.


241-241: JSDoc formatting update (LGTM)

No functional impact.

src/test/integration_tests/nc/cli/test_cli_upgrade.test.js (3)

79-86: Formatting-only change (LGTM)

No behavior change.


107-114: Formatting-only change (LGTM)

No behavior change.


134-149: Test data formatting adjustments (LGTM)

Structure and values are preserved; just condensed formatting.

src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js (14)

16-21: Import formatting (LGTM)

Readability improved, no functional change.


24-30: Import formatting (LGTM)

Consistent style, no behavior change.


38-38: Template string formatting (LGTM)

No behavior change.


49-49: Template string formatting (LGTM)

No behavior change.


60-60: Template string formatting (LGTM)

No behavior change.


377-379: Hosts obj shape (LGTM)

Top-level host entries are correct.


387-390: Hosts obj shape (LGTM)

Top-level host entries are correct.


436-438: Test data formatting (LGTM)

No behavior change.


571-571: Spread options (LGTM)

Clearer and equivalent.


797-797: Adapt to new return shape (LGTM)

Using res.upgrade_info matches the manager changes.


809-812: Assert “no upgrade required” message (LGTM)

Matches manager behavior.


849-849: Adapt to new return shape (LGTM)

Prepending res.upgrade_info to successful_upgrades matches new contract.


869-870: Destructuring formatting (LGTM)

Readability improvement.


895-902: Destructuring formatting (LGTM)

Readability improvement.

Comment on lines +58 to +61
write_stdout_response(
upgrade_res.code || ManageCLIResponse.UpgradeSuccessful,
upgrade_res.upgrade_info, { expected_version, expected_hosts }
);
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Dynamic CLI response (LGTM) — consider not emitting “started” event when no upgrade is required

The stdout handling looks correct. However, we currently emit CONFIG_DIR_UPGRADE_STARTED before learning that no upgrade is needed. To avoid misleading events, gate (or defer) the “started” event to cases where an upgrade actually runs.

If you adopt a consistent return shape with a code on success, this becomes straightforward:

-        new NoobaaEvent(NoobaaEvent.CONFIG_DIR_UPGRADE_STARTED).create_event(undefined, { expected_version, expected_hosts }, undefined);
-
         validate_expected_version(expected_version, skip_verification);
         if (!expected_hosts) dbg.warn('expected_hosts flag is empty, config dir upgrade will be performed without hosts version verification');

         const nc_upgrade_manager = new NCUpgradeManager(config_fs, { custom_upgrade_scripts_dir });
         const upgrade_res = await nc_upgrade_manager.upgrade_config_dir(expected_version, expected_hosts, { skip_verification });
         if (!upgrade_res) throw new Error('Upgrade config directory failed', { cause: upgrade_res });
+        // Emit "started" only when an upgrade actually starts (i.e., not NoUpgradeRequired)
+        if ((upgrade_res.code?.code || ManageCLIResponse.UpgradeSuccessful.code) === ManageCLIResponse.UpgradeSuccessful.code) {
+            new NoobaaEvent(NoobaaEvent.CONFIG_DIR_UPGRADE_STARTED).create_event(undefined, { expected_version, expected_hosts }, undefined);
+        }

         write_stdout_response(
             upgrade_res.code || ManageCLIResponse.UpgradeSuccessful,
             upgrade_res.upgrade_info, { expected_version, expected_hosts }
         );

🏁 Script executed:

#!/bin/bash
# Search for CONFIG_DIR_UPGRADE_STARTED and show context in src/manage_nsfs/upgrade.js
rg -n "CONFIG_DIR_UPGRADE_STARTED" -A3 -B3 src/manage_nsfs/upgrade.js || true

# Also display lines 1-100 of the file for broader context
sed -n '1,100p' src/manage_nsfs/upgrade.js

Length of output: 5408


🏁 Script executed:

#!/bin/bash
# Locate manage_nsfs_cli_responses.js
rg -l "UpgradeSuccessful" -g "src/**/manage_nsfs_cli_responses.js"

# Show the definition of ManageCLIResponse.UpgradeSuccessful
rg -n "UpgradeSuccessful" -A3 -B3 src/manage_nsfs/manage_nsfs_cli_responses.js

Length of output: 780


🏁 Script executed:

#!/bin/bash
# Show the implementation of upgrade_config_dir in NCUpgradeManager
rg -n "upgrade_config_dir" -A30 -B5 src/upgrade/nc_upgrade_manager.js

Length of output: 3530


Defer CONFIG_DIR_UPGRADE_STARTED event until an upgrade actually runs

Remove the unconditional “started” event at the top of start_config_dir_upgrade and emit it only when an upgrade is kicked off (i.e. not when there’s nothing to do).

• File: src/manage_nsfs/upgrade.js
• Remove the initial
js new NoobaaEvent(NoobaaEvent.CONFIG_DIR_UPGRADE_STARTED) .create_event(undefined, { expected_version, expected_hosts }, undefined);
• After obtaining upgrade_res, but before write_stdout_response, add a guard that skips the event when upgrade_res.code === ManageCLIResponse.NoUpgradeRequired. For example:

--- a/src/manage_nsfs/upgrade.js
+++ b/src/manage_nsfs/upgrade.js
@@ async function start_config_dir_upgrade(user_input, config_fs) {
-        // early “started” event here removed

         validate_expected_version(expected_version, skip_verification);
         if (!expected_hosts) dbg.warn('expected_hosts flag is empty, config dir upgrade will be performed without hosts version verification');

         const nc_upgrade_manager = new NCUpgradeManager(config_fs, { custom_upgrade_scripts_dir });
         const upgrade_res = await nc_upgrade_manager.upgrade_config_dir(expected_version, expected_hosts, { skip_verification });
         if (!upgrade_res) throw new Error('Upgrade config directory failed', { cause: upgrade_res });
+        // Emit “started” only when an actual upgrade runs (not when no upgrade is required)
+        if ((upgrade_res.code?.code || ManageCLIResponse.UpgradeSuccessful.code)
+            === ManageCLIResponse.UpgradeSuccessful.code
+        ) {
+            new NoobaaEvent(NoobaaEvent.CONFIG_DIR_UPGRADE_STARTED)
+                .create_event(undefined, { expected_version, expected_hosts }, undefined);
+        }

         write_stdout_response(
             upgrade_res.code || ManageCLIResponse.UpgradeSuccessful,
             upgrade_res.upgrade_info, { expected_version, expected_hosts }
         );
🤖 Prompt for AI Agents
In src/manage_nsfs/upgrade.js around lines 58 to 61, remove the unconditional
emission of the CONFIG_DIR_UPGRADE_STARTED event at the start of
start_config_dir_upgrade. Instead, after obtaining upgrade_res but before
calling write_stdout_response, add a conditional check to emit the
CONFIG_DIR_UPGRADE_STARTED event only if upgrade_res.code is not equal to
ManageCLIResponse.NoUpgradeRequired, ensuring the event is only emitted when an
upgrade actually runs.

Comment on lines +406 to +408
const system_data = {
[hostname]: { current_version: pkg.version, other_hostname: { current_version: pkg.version } }
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Fix nested host in system_data

In this test, other_hostname is nested under the primary host, which is likely accidental. Make both hosts top-level for consistency (similar to the other tests).

-            const system_data = {
-                [hostname]: { current_version: pkg.version, other_hostname: { current_version: pkg.version } }
-            };
+            const system_data = {
+                [hostname]: { current_version: pkg.version },
+                other_hostname: { current_version: pkg.version }
+            };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const system_data = {
[hostname]: { current_version: pkg.version, other_hostname: { current_version: pkg.version } }
};
const system_data = {
[hostname]: { current_version: pkg.version },
other_hostname: { current_version: pkg.version }
};
🤖 Prompt for AI Agents
In src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js around
lines 406 to 408, the system_data object incorrectly nests other_hostname inside
the primary hostname object. Refactor system_data so that both hostname and
other_hostname are top-level keys within the object, each with their own
current_version property, to maintain consistency with other tests.

Comment on lines +114 to +121
const message = 'config_dir_version on system.json and config_fs.config_dir_version match, nothing to upgrade';
dbg.warn(`upgrade_config_dir: ${message}`);
return {
code: ManageCLIResponse.NoUpgradeRequired,
upgrade_info: {
detail: message
}
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Return NoUpgradeRequired instead of throwing (LGTM) — suggest standardizing return shape

Good change aligned with PR goal. To simplify callers (and avoid fallbacks), consider always including a code on success as well, so the return shape is consistent in all cases.

Example follow-up in the success path (see Lines 137-139 comment).

🤖 Prompt for AI Agents
In src/upgrade/nc_upgrade_manager.js around lines 114 to 121, the return object
on the no-upgrade path should always include a code property to standardize the
return shape. Modify the return statement to include a code field (e.g.,
ManageCLIResponse.NoUpgradeRequired) alongside upgrade_info, ensuring all
success returns have a consistent structure with a code and upgrade_info object.

Comment on lines +137 to +139
return {
upgrade_info: this_upgrade
};
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Unify return shape: include success code in result

Return a code in the success path as well to make the contract consistent and remove the need for special-casing in callers.

-        return {
-            upgrade_info: this_upgrade
-        };
+        return {
+            code: ManageCLIResponse.UpgradeSuccessful,
+            upgrade_info: this_upgrade
+        };

To ensure no other call sites assume the old return type, run:


🏁 Script executed:

#!/bin/bash
# Find all upgrade_config_dir call sites and show surrounding context
rg -n -A3 -B3 $'upgrade_config_dir\\('

Length of output: 7044


🏁 Script executed:

#!/bin/bash
sed -n '760,830p' src/test/unit_tests/nc/configuration/test_nc_upgrade_manager.test.js

Length of output: 4109


🏁 Script executed:

#!/bin/bash
rg -n "ManageCLIResponse" src/upgrade/nc_upgrade_manager.js

Length of output: 208


🏁 Script executed:

#!/bin/bash
sed -n '1,200p' src/manage_nsfs/upgrade.js

Length of output: 5069


Unify return shape in upgrade_config_dir
Include a code field on the successful return value so callers can rely on a consistent response shape:

--- a/src/upgrade/nc_upgrade_manager.js
+++ b/src/upgrade/nc_upgrade_manager.js
@@ 134,7 +134,9 @@ class NCUpgradeManager {
-        return {
-            upgrade_info: this_upgrade
-        };
+        return {
+            code: ManageCLIResponse.UpgradeSuccessful,
+            upgrade_info: this_upgrade
+        };

• File: src/upgrade/nc_upgrade_manager.js (around line 137)
• Callers in manage_nsfs/upgrade.js already handle upgrade_res.code || ManageCLIResponse.UpgradeSuccessful.
• Unit tests only inspect res.upgrade_info and will continue to pass unchanged.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return {
upgrade_info: this_upgrade
};
return {
code: ManageCLIResponse.UpgradeSuccessful,
upgrade_info: this_upgrade
};
🤖 Prompt for AI Agents
In src/upgrade/nc_upgrade_manager.js around lines 137 to 139, the return object
from the function lacks a 'code' field, causing inconsistency with other return
shapes. Modify the return statement to include a 'code' property with a value
indicating success, such as ManageCLIResponse.UpgradeSuccessful, alongside the
existing 'upgrade_info' field. This ensures callers can rely on a consistent
response structure without affecting existing unit tests.

Copy link
Contributor

@romayalon romayalon left a comment

Choose a reason for hiding this comment

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

LGTM

@jackyalbo jackyalbo changed the title Remove error on No upgrade required NC | Remove error on No upgrade required Aug 10, 2025
@jackyalbo jackyalbo merged commit 97296e3 into noobaa:master Aug 10, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants