Skip to content

feat(vms): a Virtual Machines card where the module answers - #25

Merged
inkly merged 2 commits into
ReCasaOS:mainfrom
Vinz2168:feat/vm-module-entry
Oct 12, 2026
Merged

inkly merged 2 commits into
ReCasaOS:mainfrom
Vinz2168:feat/vm-module-entry

Conversation

@Vinz2168

@Vinz2168 Vinz2168 commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

The small dashboard PR from ReCasaOS/CasaOS#18: the card, the launcher entry and the route for the opt-in virtual machine module (Vinz2168/CasaOS-VirtManagement), kept apart from the page itself.

What it does

  • VirtualMachines/entry.js asks GET /v2/virt_management/host once per page load. The card joins Files and the App Store only when the module answers through the gateway; a 404 means it is not installed and is not asked again, any other failure is asked again next time.
  • The card opens the page in a modal, or on #/vms when App launching sends it to a new tab. The App launching exception list offers "Virtual Machines" only where the module is.
  • The page is a lazy chunk. In this PR it is only its frame (title and close); the list and the details of the machines, with noVNC, come in the next PR together with their en_US.json strings.

A box without the module downloads nothing beyond entry.js and the icon; the HTTP client is loaded only when the probe runs.

Files outside src/components/VirtualMachines/: AppSection.vue (the card), AppCard.vue (open it), appLaunchPreference.js (casaos:virtual-machines), AppLaunchModal.vue, route.js (#/vms), one string in en_US.json / it_IT.json.

Checks: lint 0 errors, build OK, new entry.spec.js (3 tests on the probe); the rest of the suite fails on exactly the same tests as main.

When the core reads /etc/casaos/modules/virt.json, the probe can ask the core instead of the module; I kept it to the gateway for now, as agreed in #18.

The dashboard side of the opt-in virtual machine module
(CasaOS-VirtManagement, ReCasaOS/CasaOS#18), kept apart from the page so it
can be reviewed on its own:

- entry.js asks /v2/virt_management/host once per page load; the card joins
  Files and the App Store only when the module answers through the gateway
  (a 404 means not installed and is not asked again)
- the card opens the page in a modal, or on #/vms when App launching sends
  it to a new tab; the launcher list offers it only where the module is
- the page is a lazy chunk; here it is only its frame (title and close),
  the list and details of the machines come in the next PR

A box without the module downloads nothing beyond this file and the icon.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@inkly inkly left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, this is what I hoped for: small, the page stays a lazy chunk, and a box without the module downloads only entry.js and the icon. I read the whole diff and ran nothing yet. Two things before I merge it:

  1. The probe is on the path that draws the app grid. AppSection.vue does await hasVirtualMachines() before it builds the list, and the probe has no timeout. On a box whose gateway answers slowly, or where /v2/virt_management/host hangs instead of failing, the grid (Files, the App Store, every app) waits for it. Could the list be built without waiting, and the card added when the probe answers? (hasVirtualMachines().then(...) pushing vmApplication() into the list; the saved order already keeps its place by name.) Failing that, a short timeout on the probe (a couple of seconds) that counts as "not there, ask again next time".
  2. French. fr_FR.json has no Virtual Machines key, so a French dashboard shows it in English. "Machines virtuelles" is the usual wording; I can push it to your branch or you can add it, whichever you prefer. (The lists of machines come in your next PR with their strings: same for French, I will send it when it is up.)

Smaller, no change needed: the 404-means-not-installed rule and asking again after any other failure are the right way round, and the three tests pin them.

The grid is drawn as soon as the apps are read; the Virtual Machines card
joins it when the probe answers, at the place the saved order has for it.
A grid read again keeps the card it already shows, so it does not blink.

A saved order that has the card is saved again only once the probe has
answered: saving it while the probe is out would drop the card's name and
send the card to the end.

Also "Machines virtuelles" in French.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Vinz2168

Copy link
Copy Markdown
Contributor Author

Thanks! Both are in 4789c3e.

The probe no longer holds up the grid. getList draws the grid without waiting, and hasVirtualMachines().then(...) adds the card at the place the saved order has for it. When the grid is read again (an install, an update) it keeps the card it already shows, so the card does not disappear and come back.

One catch with "the saved order already keeps its place by name": getList saves the order as soon as the list differs from the saved one. If it did that while the probe was still out, the list would have no card yet, the saved order would lose "Virtual Machines", and the card would come back at the end. So a saved order that has the card is saved again only once the probe has answered. If the answer is "not there", it is saved without the card, as before. I moved the sorting into sortApps so both paths use it.

One thing that changes: on a box with no saved order yet, the card goes at the end of the grid instead of right after Files, because the order is saved before the probe answers. If you'd rather keep it next to Files there too, I can do that.

Three tests in AppSection.spec.js pin this down: the card lands at its saved place, it is added only once when several reads of the grid wait on the probe, and the saved order loses the card only once the probe says it is not there.

French: I added "Machines virtuelles".

@inkly

inkly commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

Thanks, both are what I asked for. I read the second commit: the grid draws without waiting, the card joins at its place, once however many reads wait on the probe, and a saved order that has the card is not saved without it while the probe is out. The three tests pin that, and "Machines virtuelles" is right.

On a box with no saved order yet, the card at the end of the grid is fine: the owner can move it, and it is not worth a special case.

One thing, small, and it can go in your next PR if you prefer: hasVirtualMachines() answers false both for a 404 (not installed) and for any other failure (a 502 while the gateway restarts), and addVmCardWhenThere drops "Virtual Machines" from the saved order as soon as it gets false. After one transient failure the card would come back at the end of the grid instead of at its place. If the probe said "unknown" for a failure that is not a 404 (resolve null, say) and only a plain false dropped the card from the saved order, the position would survive. A test next to the third one would pin it.

@inkly
inkly merged commit 04e213b into ReCasaOS:main Oct 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants