Classic confinement for grafito

To make the review of your request easier, please use the following template to provide all the required details and also include any other information that may be relevant.


This is the log I see when I run it without classic confinement:

$ grafito                      
2025-06-06T14:08:20.024732Z   INFO - grafito: Starting Grafito server on 127.0.0.1:3000
2025-06-06T14:08:20.024733Z   WARN - grafito: Basic Authentication is DISABLED. To enable, set GRAFITO_AUTH_USER and GRAFITO_AUTH_PASS environment variables.
2025-06-06T14:08:20.024837Z   INFO - kemal: [development] Kemal is ready to lead at http://127.0.0.1:3000
2025-06-06T14:08:26.221941Z   INFO - kemal: 200 GET /?priority=5&col-visible-timestamp=on&col-visible-hostname=on&col-visible-unit=on&col-visible-priority=on&col-visible-message=on 1.37ms
2025-06-06T14:08:26.246603Z  DEBUG - grafito: Received /services request
2025-06-06T14:08:26.246603Z  DEBUG - journalctl: Executing Journalctl.known_service_units
2025-06-06T14:08:26.246618Z  DEBUG - journalctl: Generated systemctl command: ["systemctl", "list-units", "--type=service", "--all", "--no-legend", "--plain"]
2025-06-06T14:08:26.247327Z  ERROR - journalctl: Error executing systemctl for known_service_units.
Error executing process: 'systemctl': Permission denied (File::AccessDeniedError)
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from /snap/grafito/x1/bin/grafito in '??'
  from ???

2025-06-06T14:08:26.247346Z   INFO - kemal: 500 GET /services 767.84µs
2025-06-06T14:08:26.251502Z  DEBUG - grafito: Received /logs request with query params: URI::Params{"q" => [""], "unit" => [""], "tag" => [""], "hostname" => [""], "since" => [""], "priority" => ["5"], "col-visible-timestamp" => ["on"], "col-visible-hostname" => ["on"], "col-visible-unit" => ["on"], "col-visible-priority" => ["on"], "col-visible-message" => ["on"]}

I understand that strict confinement is generally preferred over classic.

I’ve tried the existing interfaces to make the snap to work under strict confinement.

Note that snappy-debug can be used to identify possible required interfaces. See https://snapcraft.io/docs/debug-snaps for more information.

This request has been added to the queue for review by the @reviewers team.

Hello @Abuelodelanada,

Since grafito is a log viewer snap, it does not fall into any of the supported categories for classic confinement, therefore, the requirement cannot be satisfied (#reject).

Regarding the error you’re encountering, it seems that your snap is attempting to run systemctl list-units. As a log viewer, isn’t it expected to simply read logs and apply filtering to them?

@reviewers, what are your thoughts on this?

1 Like

Hello @yomonokio !

It is used to filter logs by systemd unit:

image

This way you can see:

You could use a system-files interface with read-only access to /etc/systemd/system and /lib/systemd/system to obtain the list of .service files instead, this would likely be acceptable security wise …

Without fitting a matching category (which exist for a reason to only allow pre-checked types of apps that the architects reviewed in advance with the security team for being acceptable) there is simply no way this app gets accepted for classic confinement …

It’s not my app, I’m just a user trying to contribute the snap.

Thanks @ogra!!

So lets do a little research …

Taking a quick look at the code, it calls:

systemctl list-units --type=service --all --no-legend --plain

And then it rips of all actual info except for the unit name itself:

So it does not even care about the additional info that the systemctl call returns …

Judging by the output I get on my machine, apparently systemctl even ignores all of /etc/systemd/system in that call

So what you could do in packaging now is to ship a script called systemctl in your snap that looks like:

#! /bin/sh

for line in $(ls /lib/systemd/system/*.service); do 
    echo $(basename $line) foo
done

That should give you the same output in a format the code of grafito can process (you need “foo” there in the printed output so grafito finds something to rip off at the end of the line with its “line.split…” call)

Indeed it would be cleaner if upstream would just not call systemctl at all and do the ls themselves from their code to make it easier for you to roll a snap, but there is definitely a way to hack around that limitation in packaging and make it work as a strict snap …

2 Likes

There is now a compile-time option that disables the call to systemctl

2 Likes