Skip to content

Implement opt-out of automated updates from the Software Center UI #8101

Closed
NethServer/ns8-core
#1283

Description

@DavidePrincipi

In a cluster with an active Subscription, overnight automatic application updates are always enabled. Opting out is currently possible only through CLI commands, which is not discoverable and error-prone for administrators. The purpose of this feature is to expose the opt-out choice directly in the Software Center UI, implementing the approved design from #7976.

Proposed solution

Implement the UI approved in the design issue #7976 (Figma mockups):

Image
  • Add global actions to enable/disable automatic application updates from Software Center > Updates
  • Add per-application enable/disable automatic updates actions from:
    • Software Center > Installed
    • Applications section
  • Add inline notifications reflecting the global automatic updates status
  • Add an "Updates disabled" status tag for applications excluded from automatic updates
  • Update empty states and related screens
  • Replace all "instance" and "apps" labels with "applications"
  • Add dedicated community states without automatic updates controls (automatic updates are a Subscription feature)

Alternative solutions

Keep the current CLI-only opt-out procedure. Discarded: it is undocumented for most administrators and does not fit the Software Center user experience.

Additional context

The design work, mockups, and review discussion are in #7976 (approved by @DavidePrincipi and @andre8244).

See also

Activity

  1. added this to the NethServer 8.10 milestone on Jul 9, 2026
  2. DavidePrincipi commented on Jul 10, 2026

    @DavidePrincipi
    MemberAuthor

    @stephdl I started the backend implementation in branch feat-8101, you can open a PR directly on it if you like. https://github.com/NethServer/ns8-core/tree/feat-8101

    Backend: automatic update policy (global + per-instance) NethServer/ns8-core@8bc8568

    list-modules output now includes, for each app:

    • apply_updates_is_active (bool) — cluster-wide automatic updates switch
    • subscription_is_active (bool) — whether a Nethesis subscription is active (use this to show/hide the
      automatic-updates UI, since the feature only works with a subscription)
    • per installed instance, installed[].automatic_updates (bool) — whether that specific instance is opted
      into automatic updates (default true)

    New action to change both: set-automatic-updates

    {
      "apply_updates_is_active": false,
      "instances": { "dokuwiki1": false, "dokuwiki2": true }
    }
    

    Both fields are optional — send only what changed. Unknown instance IDs return a validation-failed error
    (instance_not_found).

    Notes:

    • Automatically-run updates (nightly apply-updates timer) skip instances with automatic_updates: false;
      manual/UI-triggered updates always apply regardless of the policy.
    • Toggling apply_updates_is_active also re-syncs the systemd apply-updates.timer on the backend — no
      extra call needed from the frontend.

    Docs: docs/core/updates.md, docs/core/database.md (cluster/module_automatic_update key).

  3. moved this from ToDo to In Progress in NethServeron Jul 30, 2026
  4. stephdl commented on Aug 4, 2026

    @stephdl
  5. stephdl commented on Aug 28, 2026

    @stephdl

    QA — core 3.22.0-dev.1 — Automatic updates opt-out (UI)

    Scope: UI testing only. When a step fails, note it and investigate both the
    frontend and the backend, since the UI reads list-modules and writes through
    the set-automatic-updates cluster action.

    PR: NethServer/ns8-core#1283 (backend + frontend), NethServer/ns8-core#1247 (frontend)

    Where the controls live

    Three pages are involved. They do not expose the same controls, so read this
    table before starting: it tells you what must be present on each page, and,
    just as important, what must not be there.

    Page URL Cluster-wide toggle "Automatic updates disabled" banner Per-instance toggle + tag Updates tab
    Software center /software-center yes, page kebab yes no yes
    Applications /applications-center yes, page kebab yes yes, row kebab no
    Application instances /software-center/app-instances/<app> no no yes, row kebab no

    Vocabulary used below:

    • Cluster-wide toggle: the page kebab menu entry Enable / Disable automatic
      updates
      . It switches automatic updates for the whole cluster.
    • Per-instance toggle: the same entry inside the kebab of a single
      application row. It excludes one application from automatic updates.
    • Updates disabled tag: the tag shown on an application row that has been
      excluded.

    Subscription gates everything

    The whole feature is hidden without an active subscription. The QA therefore
    runs in two passes: first without a subscription, to check that nothing leaks,
    then with a subscription, to test the feature itself. Do not skip the first
    pass, it is the cheapest way to catch a broken condition.

    1. Preconditions

    • Cluster running core:3.22.0-dev.1
    • No subscription active at this stage
    • At least 3 application instances installed, 2 of them from the same app
      (for example dokuwiki1 and dokuwiki2)
    • At least 1 instance with an update available (use add-module ghcr.io/nethserver/dokuwiki:1.1.3)
    • Browser console open during the whole session, to catch Vue errors

    Part A — Without subscription

    Nothing related to automatic updates must be visible. Everything else must keep
    working exactly as before.

    2. Software center (/software-center)

    • The page kebab does not contain Enable / Disable automatic updates
    • The kebab still contains Go to Core applications and Go to Software
      repositories
      , and both navigate correctly
    • No Automatic updates disabled banner anywhere on the page
    • Reload software repositories still works

    3. Applications page (/applications-center)

    • The page kebab does not contain the cluster-wide toggle
    • No application row kebab offers Disable automatic updates
    • No Updates disabled tag on any row
    • No Automatic updates disabled banner
    • The other row actions still work: restart, clone, move, favourites, uninstall

    4. Application instances page (/software-center/app-instances/<app>)

    • No per-instance automatic updates entry in any row kebab
    • No Updates disabled tag
    • The other row actions still work

    5. Updates tab without subscription

    • The Updates tab lists the available updates normally
    • The Applications update section is shown, but without the note
      saying updates are installed automatically
    • Update all applications still works, countdown included
    • Updating a single application still works

    Part B — Activate the subscription

    6. Activation

    • Register the cluster in Settings > Subscription
    • Reload the Software center page
    • The cluster-wide toggle now appears in the page kebab
    • It reflects the real state: after a fresh activation automatic updates are
      normally enabled, so the entry should read Disable automatic updates
    • The same entry appears on the Applications page
    • Per-instance entries appear on the Applications page and on the application
      instances page

    Part C — Software center, with subscription (/software-center)

    7. Page toolbar

    • The cluster-wide toggle label matches the current state
    • Its icon follows the state: play when disabled, pause when enabled
    • No per-instance toggle is offered on this page

    8. Cluster-wide toggle — disable

    • Open the page kebab, click Disable automatic updates
    • The modal refers to the whole cluster and mentions the security risk
    • The primary button reads Disable
    • Confirm: the task runs and the modal closes on success
    • The kebab entry now reads Enable automatic updates
    • A warning banner Automatic updates disabled appears at the top of the page
    • Reload the page: banner and kebab label are still consistent

    9. Cluster-wide toggle — enable

    • Click the banner action button Enable automatic updates
    • The modal states that applications previously excluded stay excluded
    • The primary button reads Enable
    • Confirm: the banner disappears and the kebab label flips back
    • Reopen the modal and click Cancel: nothing changes

    10. Modal error and loading behaviour

    Test this once here; the same modal component is reused on the other two pages.

    • While the task runs, the primary button is disabled and the modal shows its
      loading state
    • While the task runs, clicking outside the modal does not close it
    • Force a failure (for example stop the cluster agent, or cut the network
      before confirming): the modal stays open and shows an inline error
    • Close and reopen the modal: the previous error is gone

    11. Updates tab

    The update logic itself was not modified: only the layout of this tab changed.
    The core and applications updates are now two separate sections, the update
    button moved inside the applications section, and the empty state gained a guard
    on listing errors. Treat this part as a regression check.

    • Go to the Updates tab
    • A Core update section with its description is shown when a core update
      is available
    • An Applications update section lists the applications to update
    • The note about automatic installation is now displayed, since a subscription
      is active and the cluster-wide toggle is enabled
    • Disable the cluster-wide toggle: the note disappears. Re-enable it
    • Update all applications starts a 10 seconds countdown notification
    • Cancel during the countdown aborts the update
    • Letting the countdown finish starts the update and reports progress
    • With no update pending, the rocket empty state Cluster is up to date is
      shown, with the description No updates are currently available
    • Make the module listing fail (stop the cluster agent, then reload the tab):
      the error notification is displayed and the Cluster is up to date empty
      state is not shown

    12. Updates available banner

    • On the All and Installed tabs, a warning banner Updates available
      is displayed when updates exist
    • Its action button switches to the Updates tab
    • The banner is not displayed while already on the Updates tab
    • Text is correct when only core updates exist
    • Text is correct when only application updates exist, singular and plural
    • Text is correct when both core and application updates exist

    Part D — Applications page (/applications-center)

    13. Page toolbar

    • The page kebab contains the cluster-wide toggle, in the same state as seen
      on the Software center page
    • Go to Core applications button works
    • Go to Software center kebab entry works
    • Disabling the cluster-wide toggle here shows the Automatic updates
      disabled
      banner on this page too
    • Re-enable it before continuing

    14. Per-instance toggle

    • Each application row kebab offers Disable automatic updates
    • Pick one instance and disable it: the modal names that instance and says it
      can still be updated manually
    • Confirm: the Updates disabled tag appears on that row only
    • The other rows keep no tag
    • Reload the page: the tag is still there
    • Re-enable it from the same row: the tag disappears and the modal wording is
      the enable variant
    • Leave one instance excluded for the next steps

    15. Interaction between the two toggles

    This is the part most likely to break, so run it on this page specifically.

    • Right after using a per-instance toggle, open the page kebab and use the
      cluster-wide toggle: the modal must describe the cluster, not the
      instance previously selected
    • Disable the cluster-wide toggle: the per-instance entries and the Updates
      disabled
      tags disappear from every row
    • Re-enable the cluster-wide toggle: the instance excluded in step 14 still
      shows its Updates disabled tag

    Part E — Application instances page (/software-center/app-instances/<app>)

    Reach it from the Software center by clicking an application, then its instances.
    Use the application that has two instances.

    16. Per-instance toggle

    • The page kebab does not offer a cluster-wide toggle
    • No Automatic updates disabled banner is shown on this page
    • Each instance row kebab offers Disable automatic updates
    • Disable it on one instance: the tag Updates disabled appears on that
      instance only
    • Go back to /applications-center: the same instance shows the same tag
    • Change the state from the Applications page, come back here: the state
      matches

    17. Gating

    • Disable the cluster-wide toggle from another page, come back here: the
      per-instance entries and tags are gone
    • Re-enable it: they come back with the previous per-instance states

    Part F — Cross-cutting checks

    18. Manual update still possible

    Excluding an instance must never block a manual update: the policy is only
    applied to updates started by the apply-updates timer.

    • Exclude from automatic updates an instance that has an update pending
    • Update it manually from its row menu: the update runs normally
    • Run Update all applications from the Updates tab: the excluded instance
      is updated too

    19. Overnight end-to-end check

    The exclusion is only enforced by the apply-updates timer, so it cannot be
    observed from the interface alone. This is the one step that leaves the UI, and
    it is the real proof that the opt-out works.

    The timer runs Tue..Fri 00:00 with a random delay of up to 6 hours, so plan it
    on a Monday to Thursday evening and read the result the next morning.

    Setup, the evening before:

    • Subscription active and cluster-wide automatic updates enabled
    • At least two instances have an update pending
    • Exclude one of them from automatic updates, from the UI
    • Leave the other one included
    • Note both versions, visible in the Applications page
    • Check the timer is armed: systemctl status apply-updates.timer, and note
      the Trigger time
    • Leave the node powered on for the night

    The next morning:

    • The included instance has been updated: its new version shows in the UI and
      no update is listed for it any more
    • The excluded instance still has its update pending, and still shows the
      Updates disabled tag
    • journalctl -u apply-updates shows the skip line for the excluded instance
    • Repeat with the cluster-wide toggle disabled: after the night, nothing was
      updated at all

    Faster variant, if you cannot wait for the night: run systemctl start apply-updates.service and check the same three points. It takes the same code
    path as the timer.

    20. Subscription removal

    • Exclude one instance from automatic updates
    • Remove the subscription in Settings > Subscription
    • Reload the pages: every automatic updates control and tag disappears again,
      as in Part A
    • Re-register the subscription: the excluded instance still shows its
      Updates disabled tag

    21. Regressions

    • Clicking the already active side menu entry produces no NavigationDuplicated
      error in the browser console
    • Cloning an application refreshes the app drawer and lists the new instance
    • Moving an application to another node updates the drawer accordingly
    • The wording says "application" instead of "instance" across the Software
      center, the Applications page and the clone/move modal
    • No untranslated key is visible, no raw software_center.* string on screen

    22. Cleanup

    • Re-enable automatic updates on every instance excluded during the tests
    • Restore the cluster-wide automatic updates toggle to its original value
    • Restore the subscription to its original state
  6. removed their assignment
    on Aug 28, 2026
  7. moved this from In Progress to Testing in NethServeron Aug 28, 2026
  8. added
    testingPackages are available from testing repositories
    on Aug 28, 2026
  9. nrauso commented on Sep 16, 2026

    @nrauso

    test cases VERIFIED

  10. added
    verifiedAll test cases were verified successfully
    on Sep 16, 2026
  11. removed
    testingPackages are available from testing repositories
    on Sep 16, 2026
  12. moved this from Testing to Verified in NethServeron Sep 16, 2026
  13. DavidePrincipi commented on Sep 18, 2026

    @DavidePrincipi
    MemberAuthor
  14. moved this from Verified to Done in NethServeron Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    UXUser experience issuesverifiedAll test cases were verified successfully

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions