Skip to content

Bug 2068283 - Generic console support - #1339

Open
fiji-flo wants to merge 13 commits into
mozilla:enterprise-mainfrom
fiji-flo:generic-console
Open

Bug 2068283 - Generic console support#1339
fiji-flo wants to merge 13 commits into
mozilla:enterprise-mainfrom
fiji-flo:generic-console

Conversation

@fiji-flo

@fiji-flo fiji-flo commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Description

I'll edit this later, opening for sharing early.

Bugzilla: Bug-2068283

Every enterprise deployment currently requires a per-customer repack that bakes the console address into the AutoConfig file (firefox.cfg). This adds a generic build: one artifact that ships without a console address and gets configured at first startup, so the same build can serve any organization (downloads, evaluations, QA).

Implementation Details:

  • --with-enterprise-console-url still bakes a real address in for repacks. Without it the build is generic and firefox.cfg carries the placeholder FIREFOX_ENTERPRISE_GENERIC
  • At startup, before profile selection, the placeholder is resolved in this order:
    1. the MOZ_ENTERPRISE_CONSOLE_URL environment variable (test harness override),
    2. the consoleAddress persisted in felt.json (UAppData) by the setup dialog,
    3. otherwise a modal pre-profile setup dialog (chrome://felt/content/consoleSetup.xhtml, FELT UI only; skipped under MOZ_AUTOMATION and in background-task mode) asks for the address, persists it to felt.json, and relaunches so the early consumers (crash reporter ServerURL, update URL, FELT connection) see the configured value from the start.
  • --reset-console-address clears the stored address so the dialog runs again.
  • The resolution logic lives once, in the new IO-free enterprise-console crate (toolkit/components/enterprise/rust), shared by all native consumers: browser startup through the felt crate's FFI (XRE_ReadEnterpriseConsoleAddress / XRE_ParseEnterpriseServerURL in toolkit/xre/CreateAppData.cpp), and the standalone crash reporter client. ConsoleClient.sys.mjs mirrors it in JS.
  • mozrunner and Marionette set MOZ_ENTERPRISE_CONSOLE_URL to a closed local port by default so generic builds never block on the dialog under automation.

Screenshots

image

Testing

  • Added tests
  • Manual testing performed

@lissyx
lissyx marked this pull request as draft August 26, 2026 11:01
Comment thread toolkit/xre/CreateAppData.cpp Outdated
NS_ENSURE_SUCCESS(rv, rv);
}

if (serverUrl.EqualsLiteral(ENTERPRISE_CONSOLE_PLACEHOLDER)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Out of safety I think this should be reversed: if the value is not the place holder, immediately return NS_ERROR_NOT_AVAILABLE (or maybe NS_ERROR_INVALID_ARG would be more meaningful

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's not the flow here. If the value is not the place holder we need to continue. NS_ERROR_NOT_AVAILABLE is only returned if there's no URL stored / in evn.

Comment on lines +10 to +13
# FIREFOX_ENTERPRISE_GENERIC is a placeholder: on first launch the console
# setup dialog asks for the address and persists it in felt.json. Repacks
# replace it with the actual console address.
enterprise.console.address=FIREFOX_ENTERPRISE_GENERIC

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

But then we break running local builds without requiring extra step from developpers, which adds friction

@lissyx lissyx Aug 26, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd rather prefer that we do not change the default distribution.ini to such placeholder. We may at some point want to point it to a different instance than stage though ?

But I'd prefer if we had a dedicated repack that will set the placeholder value

This way, local build are still immediately actionable and the console setup step works like you want from the specific repack

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It can also make sure that I cannot inadvertenly have a wrong console in memory of my felt.json storage that gets picked up when running random builds, scoping the feature to those generic repacks

Comment thread toolkit/components/enterprise/modules/ConsoleClient.sys.mjs
Comment thread toolkit/components/enterprise/modules/ConsoleClient.sys.mjs
@lissyx

lissyx commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
image That looks nice!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We need to be extra careful about reviewing further changes using those function, as we may end up in a case where FeltStorage.sys.mjs and those are manipulating the same files at the same time. I think for the time being it's OK, even on macOS where we may have running processes without a window.

But maybe a naïve locking mechanism may be good to protect us for the future?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, we might want to think about this outside of this PR. Multiple Enterprise instances would read/write from that file concurrently right now.

@lissyx lissyx Aug 31, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we file a follow up for a trivial locking system (e.g. .lock file) at least? To protect us?

Other option, but it would start to get out of scope so a follow up would be nice, would be to convert the FeltStorage code to directly rely on rust so the locking could be done there?

Comment on lines +26 to +30
if (!(this._feltStorage instanceof lazy.JSONFile)) {
this._feltStorage = new lazy.JSONFile({
path: this.FELT_FILE_PATH,
});
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we rather guard with a boolean, e.g. this._initialized ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also why do we need this?

I assume it's because we hit now two call sites of FeltStorage.init() one in ConsoleClient and one in consoleSetup.js ?

nsAutoString path;
rv = file->GetPath(path);
NS_ENSURE_SUCCESS(rv, rv);
CopyUTF16toUTF8(path, aOutPath);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nsCString is safe for windows paths ? What if the path contains UTF-8 or UTF-16 chars?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

XRE_ParseEnterpriseServerURL(*mAppData);
// Ignoring nsresult. If console url is not found in a release build, the
// default server url is empty and crash reports will fail to submit.
if (CheckArg("reset-console-address") == ARG_FOUND) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So firefox --reset-console-address would allow to trigger again the dialog, but only if its distribution.ini contains the placeholder value.

At my first reading of this part of the code I was afraid, so it may be worth commenting here to make this context crystal clear

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Can you suggest an improvement to my comments?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'll try to come up with something yes

Comment thread toolkit/xre/nsAppRunner.cpp Outdated
Comment on lines +6076 to +6079
// Never block automation on the interactive setup dialog: test harnesses
// launch the browser before any console address exists (Marionette's first
// launch precedes the test setUp that provides one via distribution.ini or
// MOZ_ENTERPRISE_CONSOLE_ADDRESS) and would time out waiting for it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this becomes irrelevant if we move to making such a generic repack instead of changing the default distribution.ini value and the whole checks can be simplified

Comment thread toolkit/xre/nsAppRunner.cpp Outdated
Comment on lines +6080 to +6096
const bool enterpriseConsoleSetupAllowed =
!EnvHasValue("MOZ_AUTOMATION") && !CheckArgExists("marionette");
if (gEnterpriseConsoleSetupNeeded && enterpriseConsoleSetupAllowed &&
is_felt_ui()
# ifdef MOZ_BACKGROUNDTASKS
&& !BackgroundTasks::IsBackgroundTaskMode()
# endif
) {
rv = ShowEnterpriseConsoleSetup(mNativeApp);
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
*aExitFlag = true;
return 0;
}
if (NS_FAILED(rv)) {
return 1;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Implementing via a generic repack instead of changing local builds values, we should be able to simplify to

Suggested change
const bool enterpriseConsoleSetupAllowed =
!EnvHasValue("MOZ_AUTOMATION") && !CheckArgExists("marionette");
if (gEnterpriseConsoleSetupNeeded && enterpriseConsoleSetupAllowed &&
is_felt_ui()
# ifdef MOZ_BACKGROUNDTASKS
&& !BackgroundTasks::IsBackgroundTaskMode()
# endif
) {
rv = ShowEnterpriseConsoleSetup(mNativeApp);
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
*aExitFlag = true;
return 0;
}
if (NS_FAILED(rv)) {
return 1;
}
}
const bool enterpriseConsoleSetupAllowed = is_felt_ui()
# ifdef MOZ_BACKGROUNDTASKS
&& !BackgroundTasks::IsBackgroundTaskMode()
# endif
;
if (gEnterpriseConsoleSetupNeeded && enterpriseConsoleSetupAllowed) {
rv = ShowEnterpriseConsoleSetup(mNativeApp);
if (rv == NS_ERROR_LAUNCHED_CHILD_PROCESS || rv == NS_ERROR_ABORT) {
*aExitFlag = true;
return 0;
}
if (NS_FAILED(rv)) {
return 1;
}
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'll look at this part tomorrow.

@lissyx

lissyx commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

@fiji-flo Thanks for taking care of this, I think it's overall right, I just really want that we do not change the default build output and rather make such a "generic" repack that will run on CI

Comment thread toolkit/xre/nsAppRunner.cpp
@fiji-flo fiji-flo changed the title [DRAFT] Generic console support Bug 2068283 - Generic console support Sep 1, 2026
@fiji-flo
fiji-flo marked this pull request as ready for review September 1, 2026 21:55
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