feat(managed-by): add linux managed configuration support for Flatpak (#15729)

### What does this PR do?

On flatpak, the traditional `/usr/share/` directory is not accessible,
and rather it's accessible via `/run/host/usr/share` from within the flatpak.

This is accessible by adding: `  - "--filesystem=host-os:ro"` to our
flatpak yaml, which gives read-only support for the host file system
with the ability to access the /usr/share/podman-desktop directory via
`/run/host/usr/share/podman-desktop`.

This change allows us to detect if we are running in a flatpak
environment and change where we are finding our managed configuration
file anyways.

We use `process.env.FLATPAK_ID` throughout Podman Desktop anyways :)

### Screenshot / video of UI

<!-- If this PR is changing UI, please include
screenshots or screencasts showing the difference -->

### What issues does this PR fix or reference?

<!-- Include any related issues from Podman Desktop
repository (or from another issue tracker). -->

Closes https://github.com/podman-desktop/podman-desktop/issues/15314

### How to test this PR?

1. Create file `/usr/share/podman-desktop/default-settings.json`:

```sh
  { "telemetry.enabled": false }
```

and

`/usr/share/podman-desktop/locked.json`:

```sh
  { "locked": ["telemetry.enabled"] }
```

2. Download the Flatpak manifest.

**SPECIAL NOTE:**

- This includes the upcoming changes to node24
- This pulls from this active branch the podman desktop build
- We pre-build podman desktop to get the artifacts / cache / enable
  network access to that we can test this build
- Has the new parameter added (`host-os:ro`)

```
curl -O 135596fa62/io.podman_desktop.PodmanDesktop.yml
```

3. Build:

```
flatpak-builder --force-clean --disable-rofiles-fuse --user \
  --install-deps-from=flathub --repo=repo builddir \
  io.podman_desktop.PodmanDesktop.yml
```

4. Install:

```
flatpak --user install repo io.podman_desktop.PodmanDesktop
```

5. Start podman desktop, go to Settings > Telemetry, see that it is not
   locked. You can also check your logs and see at the very top how it
   is now loading default-settings.json and locked.json from
   `/run/host`.

Signed-off-by: Charlie Drage <charlie@charliedrage.com>
This commit is contained in:
Charlie Drage 2026-01-19 10:01:52 -05:00 committed by GitHub
parent 141bc4f5bb
commit 62f0e71c4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 43 additions and 1 deletions

View file

@ -177,6 +177,18 @@ describe('LegacyDirectories', () => {
expect(provider.getManagedDefaultsDirectory()).toBe(product.paths.managed.linux);
});
test('should return flatpak managed folder path when running on Linux in Flatpak', () => {
vi.mocked(isMac).mockReturnValue(false);
vi.mocked(isWindows).mockReturnValue(false);
vi.mocked(isLinux).mockReturnValue(true);
// biome-ignore lint/complexity/useLiteralKeys: FLATPAK_ID comes from an index signature
process.env['FLATPAK_ID'] = 'io.podman_desktop.PodmanDesktop';
provider = new LegacyDirectories();
expect(provider.getManagedDefaultsDirectory()).toBe(product.paths.managed.flatpak);
});
test('should fallback to linux managed folder path when platform is unknown', () => {
vi.mocked(isMac).mockReturnValue(false);
vi.mocked(isWindows).mockReturnValue(false);

View file

@ -103,6 +103,10 @@ export class LegacyDirectories implements Directories {
// replace %PROGRAMDATA% in the path
return product.paths.managed.windows.replace('%PROGRAMDATA%', programData);
} else if (isLinux()) {
// biome-ignore lint/complexity/useLiteralKeys: FLATPAK_ID comes from an index signature
if (process.env['FLATPAK_ID']) {
return product.paths.managed.flatpak;
}
return product.paths.managed.linux;
}
// Fallback to Linux-style path

View file

@ -21,6 +21,8 @@ import * as path from 'node:path';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import product from '/@product.json' with { type: 'json' };
import type { Directories } from './directories.js';
import { LinuxXDGDirectories } from './directories-linux-xdg.js';
@ -35,6 +37,8 @@ beforeEach(() => {
delete process.env['XDG_CONFIG_HOME'];
// biome-ignore lint/complexity/useLiteralKeys: XDG_DATA_HOME comes from an index signature
delete process.env['XDG_DATA_HOME'];
// biome-ignore lint/complexity/useLiteralKeys: FLATPAK_ID comes from an index signature
delete process.env['FLATPAK_ID'];
});
afterEach(() => {
@ -115,4 +119,21 @@ describe('LinuxXDGDirectories', () => {
expect(provider.getExtensionsStorageDirectory()).toBe(path.resolve(expectedDataDir, 'extensions-storage'));
});
});
describe('getManagedDefaultsDirectory', () => {
test('should return linux managed folder path when not running in Flatpak', () => {
provider = new LinuxXDGDirectories();
expect(provider.getManagedDefaultsDirectory()).toBe(product.paths.managed.linux);
});
test('should return flatpak managed folder path when running in Flatpak', () => {
// biome-ignore lint/complexity/useLiteralKeys: FLATPAK_ID comes from an index signature
process.env['FLATPAK_ID'] = 'io.podman_desktop.PodmanDesktop';
provider = new LinuxXDGDirectories();
expect(provider.getManagedDefaultsDirectory()).toBe(product.paths.managed.flatpak);
});
});
});

View file

@ -87,6 +87,10 @@ export class LinuxXDGDirectories implements Directories {
}
getManagedDefaultsDirectory(): string {
// biome-ignore lint/complexity/useLiteralKeys: FLATPAK_ID comes from an index signature
if (process.env['FLATPAK_ID']) {
return product.paths.managed.flatpak;
}
return product.paths.managed.linux;
}
}

View file

@ -9,7 +9,8 @@
"managed": {
"macOS": "/Library/Application Support/io.podman_desktop.PodmanDesktop",
"windows": "%PROGRAMDATA%\\Podman Desktop",
"linux": "/usr/share/podman-desktop"
"linux": "/usr/share/podman-desktop",
"flatpak": "/run/host/usr/share/podman-desktop"
}
},
"telemetry": {