Request hardware-observe auto-connection for the energy-tools snap (was Classic confinement request for energy-tools)

I’d like to request that the hardware-observe interface is granted auto-connection for the energy-tools snap

1 Like

Have you tried using the hardware-observe interface?

Your request for classic confinement could benefit from more detail on why the current interfaces are insufficient for your needs. This allows us to prioritise common problems that packagers are encountering with the current interfaces and design new ones to allow more snaps to migrate to strict confinement.

https://paste.ubuntu.com/p/dTw2py8C3T/ is my snapcraft.yaml.
I don’t know how to use the hardware-observe interface.
Could you help to give an example?

I tried to add “plugs: [hardware-observe]” in https://paste.ubuntu.com/p/Gqs2d7gmgf/ but I still encounter the error of “ValueError: Namespace Gdk not available” in https://paste.ubuntu.com/p/YShbRK2QSD/.

Did you try connecting the interface after installing it?

Try:

$ snap connect energy-tools:hardware-observe

I tried snap connect energy-tools:hardware-observe but it doesn’t work.

I have fixed the error of “ValueError: Namespace Gdk not available” by this snapcraft.yaml. However I encounter other problems below that I can not use dmidecode to get the data. I added a bash in snapcraft.yaml to debug.

user@bionic:~$ sudo dmidecode -t 11 sudo: no tty present and no askpass program specified

user@bionic:~$ dmidecode # dmidecode 3.1 /sys/firmware/dmi/tables/smbios_entry_point: Permission denied Scanning /dev/mem for entry point. /dev/mem: Permission denied

OK. I fixed the “Permission denied” by https://github.com/fourdollars/energy-tools/commit/35e888cca228fa040bbc21e689f69442b747f974.
I ask the user to use this tool with root permission when it needs.

I found another problem after I released the snap package to public.
If I install this snap package without --devmode, it failed.

$ snap install --dangerous energy-tools_1.6.5_multi.snap
energy-tools 1.6.5 installed
$ sudo energy-tools 
Energy Tools 1.6.5 for Energy Star 5/6/7/8 and ErP Lot 3
================================================================================
Which product type would you like to verify?
[1] Desktop, Integrated Desktop, and Notebook Computers
[2] Workstations
[3] Small-scale Servers
[4] Thin Clients
>> 1
--------------------------------------------------------------------------------
Which type of computer do you use?
[1] Desktop
[2] Integrated Desktop
[3] Notebook
>> 3
--------------------------------------------------------------------------------
Is there a television tuner? [y/n]
>> n
--------------------------------------------------------------------------------
Does it have switchable graphics and automated switching enabled by default?
Switchable Graphics: Functionality that allows Discrete Graphics to be disabled
when not required in favor of Integrated Graphics. [y/n]
>> n
--------------------------------------------------------------------------------
How many discrete graphics cards?
>> 0
--------------------------------------------------------------------------------
No protocol specified
Unable to init server: Could not connect: Connection refused
Traceback (most recent call last):
  File "/snap/energy-tools/x1/bin/energy-tools", line 33, in <module>
    core.process(description, args)
  File "/snap/energy-tools/x1/lib/python3.6/site-packages/energy_tools/core.py", line 639, in process
    sysinfo = SysInfo()
  File "/snap/energy-tools/x1/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 170, in __init__
    self.diagonal = self.get_diagonal()
  File "/snap/energy-tools/x1/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 92, in get_diagonal
    major = screen.get_primary_monitor()
AttributeError: 'NoneType' object has no attribute 'get_primary_monitor'

However if I installed it with --devmode, it works fine.

$ snap install --devmode --dangerous energy-tools_1.6.5_multi.snap #install
energy-tools 1.6.5 installed
$ sudo energy-tools 
Energy Tools 1.6.5 for Energy Star 5/6/7/8 and ErP Lot 3
================================================================================
Which product type would you like to verify?
[1] Desktop, Integrated Desktop, and Notebook Computers
[2] Workstations
[3] Small-scale Servers
[4] Thin Clients
>> 1
--------------------------------------------------------------------------------
Which type of computer do you use?
[1] Desktop
[2] Integrated Desktop
[3] Notebook
>> 3
--------------------------------------------------------------------------------
Is there a television tuner? [y/n]
>> n
--------------------------------------------------------------------------------
Does it have switchable graphics and automated switching enabled by default?
Switchable Graphics: Functionality that allows Discrete Graphics to be disabled
when not required in favor of Integrated Graphics. [y/n]
>> n
--------------------------------------------------------------------------------
How many discrete graphics cards?
>> 0
--------------------------------------------------------------------------------
Which storage type for /sys/block/sda?
[0] Unknown
[1] 3.5” HDD
[2] 2.5” HDD
[3] Hybrid HDD/SSD
[4] SSD (including M.2 port solutions)
>> 2

It looks like the X connection is blocked.
Do you have any idea?

You need to use the desktop interfaces in order to access the X server.

I’m not entirely sure what you’d need exactly to get your script working. OpenGL support might be required too.

I have used the desktop interfaces with OpenGL support but it still doesn’t work.

apps:
  energy-tools:
    command: desktop-launch $SNAP/bin/energy-tools
    plugs:
      - desktop
      - desktop-legacy
      - hardware-observe
      - home
      - opengl
      - unity7
      - wayland
      - x11

I still see the error.

No protocol specified
Unable to init server: Could not connect: Connection refused
Traceback (most recent call last):
  File "/snap/energy-tools/x4/bin/energy-tools", line 33, in <module>
    core.process(description, args)
  File "/snap/energy-tools/x4/lib/python3.6/site-packages/energy_tools/core.py", line 639, in process
    sysinfo = SysInfo()
  File "/snap/energy-tools/x4/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 170, in __init__
    self.diagonal = self.get_diagonal()
  File "/snap/energy-tools/x4/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 92, in get_diagonal
    major = screen.get_primary_monitor()
AttributeError: 'NoneType' object has no attribute 'get_primary_monitor'

I found some errors in dmesg.

[ 3922.546032] audit: type=1400 audit(1567909514.381:446): apparmor=“DENIED” operation=“mkdir” profile=“snap.energy-tools.energy-tools” name=“/run/user/0/” pid=4046 comm=“mkdir” requested_mask=“c” denied_mask=“c” fsuid=0 ouid=0 [ 3938.557855] audit: type=1400 audit(1567909530.393:447): apparmor=“DENIED” operation=“capable” profile=“snap.energy-tools.energy-tools” pid=4009 comm=“python3” capability=2 capname=“dac_read_search” [ 3938.557862] audit: type=1400 audit(1567909530.393:448): apparmor=“DENIED” operation=“capable” profile=“snap.energy-tools.energy-tools” pid=4009 comm=“python3” capability=1 capname=“dac_override”

1 Like

If I install it by --devmode and it works.

[ 4407.912838] audit: type=1400 audit(1567909999.748:449): apparmor=“STATUS” operation=“profile_replace” profile=“unconfined” name=“snap.energy-tools.energy-tools” pid=5405 comm=“apparmor_parser” [ 4409.272513] audit: type=1400 audit(1567910001.104:450): apparmor=“STATUS” operation=“profile_replace” profile=“unconfined” name=“snap-update-ns.energy-tools” pid=5404 comm=“apparmor_parser” [ 4409.301244] audit: type=1400 audit(1567910001.136:451): apparmor=“STATUS” operation=“profile_replace” info=“same as current profile, skipping” profile=“unconfined” name=“/snap/core/7396/usr/lib/snapd/snap-confine” pid=5408 comm=“apparmor_parser” [ 4409.301247] audit: type=1400 audit(1567910001.136:452): apparmor=“STATUS” operation=“profile_replace” info=“same as current profile, skipping” profile=“unconfined” name=“/snap/core/7396/usr/lib/snapd/snap-confine//mount-namespace-capture-helper” pid=5408 comm=“apparmor_parser” [ 4409.304735] audit: type=1400 audit(1567910001.140:453): apparmor=“STATUS” operation=“profile_replace” info=“same as current profile, skipping” profile=“unconfined” name=“snap-update-ns.core” pid=5410 comm=“apparmor_parser” [ 4409.305621] audit: type=1400 audit(1567910001.140:454): apparmor=“STATUS” operation=“profile_replace” info=“same as current profile, skipping” profile=“unconfined” name=“snap.core.hook.configure” pid=5411 comm=“apparmor_parser” [ 4442.181998] audit: type=1400 audit(1567910034.016:455): apparmor=“ALLOWED” operation=“mkdir” profile=“snap.energy-tools.energy-tools” name=“/run/user/0/” pid=5528 comm=“mkdir” requested_mask=“c” denied_mask=“c” fsuid=0 ouid=0 [ 4442.182002] audit: type=1400 audit(1567910034.016:456): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/run/user/0/” pid=5528 comm=“mkdir” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4454.248527] audit: type=1400 audit(1567910046.084:457): apparmor=“ALLOWED” operation=“capable” profile=“snap.energy-tools.energy-tools” pid=5498 comm=“python3” capability=2 capname=“dac_read_search” [ 4454.248530] audit: type=1400 audit(1567910046.084:458): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/run/user/1000/gdm/Xauthority” pid=5498 comm=“python3” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=1000 [ 4454.278663] audit: type=1400 audit(1567910046.112:459): apparmor=“ALLOWED” operation=“capable” profile=“snap.energy-tools.energy-tools” pid=5707 comm=“xrandr” capability=2 capname=“dac_read_search” [ 4454.278666] audit: type=1400 audit(1567910046.112:460): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/run/user/1000/gdm/Xauthority” pid=5707 comm=“xrandr” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=1000 [ 4454.293710] audit: type=1400 audit(1567910046.128:461): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/sys/block/” pid=5711 comm=“ls” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4454.297644] audit: type=1400 audit(1567910046.132:462): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/sys/block/” pid=5714 comm=“ls” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4457.734271] audit: type=1400 audit(1567910049.568:463): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/proc/acpi/wakeup” pid=5498 comm=“python3” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4458.911110] audit: type=1400 audit(1567910050.744:464): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/sys/devices/pci0000:00/0000:00:19.0/net/eth0/speed” pid=5498 comm=“python3” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4458.911460] audit: type=1400 audit(1567910050.744:465): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/sys/devices/pci0000:00/0000:00:19.0/net/eth0/speed” pid=5498 comm=“python3” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0 [ 4458.992939] audit: type=1400 audit(1567910050.828:466): apparmor=“ALLOWED” operation=“open” profile=“snap.energy-tools.energy-tools” name=“/sys/firmware/dmi/tables/smbios_entry_point” pid=5744 comm=“dmidecode” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0

There are still two problems right now.

First

snap connect energy-tools:hardware-observe :hardware-observe can fix the problem of dmidecode with root permission, i.e. sudo energy-tools. (Solved) I need make a store-request post for the auto connection of hardware-observe.

Second

If I execute the command by sudo energy-tools, the root can not access the normal user’s X environment. But if I execute energy-tools with normal, it can access the normal user’s X environment without any problem.

This program will need both information from dmidecode and xrandr. I made the following code snippet to demonstrate the problem.

import os
import subprocess
if os.geteuid() == 0:
    slot = subprocess.check_output("dmidecode -t 16 | grep 'Devices:' | awk -F': ' '{print $2}'", shell=True, encoding='utf8').split('\n')
    print(slot)
    for size in subprocess.check_output("dmidecode -t 17 | grep 'Size:.*MB' | awk '{print $2}'", shell=True, encoding='utf8').split('\n'):
        print(size)

    import gi
    gi.require_version('Gdk', '3.0')
    from gi.repository import Gdk
    screen = Gdk.Screen.get_default()
    major = screen.get_primary_monitor()
    width_mm = screen.get_monitor_width_mm(major)
    height_mm = screen.get_monitor_height_mm(major)
    print(width_mm)
    print(height_mm)

    (width, height) = subprocess.check_output("xrandr | grep 'connected primary' | sed 's/.*connected primary \\([0-9]*\\)x\\([0-9]*\\).*/\\1 \\2/'", shell=True, encoding='utf8').strip().split(' ')
    print(width)
    print(height)
else:
    import gi
    gi.require_version('Gdk', '3.0')
    from gi.repository import Gdk
    screen = Gdk.Screen.get_default()
    major = screen.get_primary_monitor()
    width_mm = screen.get_monitor_width_mm(major)
    height_mm = screen.get_monitor_height_mm(major)
    print(width_mm)
    print(height_mm)

    (width, height) = subprocess.check_output("xrandr | grep 'connected primary' | sed 's/.*connected primary \\([0-9]*\\)x\\([0-9]*\\).*/\\1 \\2/'", shell=True, encoding='utf8').strip().split(' ')
    print(width)
    print(height)

    slot = subprocess.check_output("dmidecode -t 16 | grep 'Devices:' | awk -F': ' '{print $2}'", shell=True, encoding='utf8').split('\n')
    print(slot)
    for size in subprocess.check_output("dmidecode -t 17 | grep 'Size:.*MB' | awk '{print $2}'", shell=True, encoding='utf8').split('\n'):
        print(size)

$ energy-tools 527 296 1920 1080 /sys/firmware/dmi/tables/smbios_entry_point: Permission denied /dev/mem: Permission denied [‘’] /sys/firmware/dmi/tables/smbios_entry_point: Permission denied /dev/mem: Permission denied

$ sudo energy-tools mkdir: cannot create directory ‘/run/user/0’: Permission denied [‘2’, ‘’] 8192 8192

No protocol specified Unable to init server: Could not connect: Connection refused Traceback (most recent call last): File “/snap/energy-tools/x16/bin/energy-tools”, line 42, in major = screen.get_primary_monitor() AttributeError: ‘NoneType’ object has no attribute ‘get_primary_monitor’

snapcraft.yaml is my current settings.

Do you have any idea to use X protocol with root permission, i.e. sudo enregy-tools?

You need to figure out why your application is trying to create /run/user/0/ when run as root and have it not do that. Even if it could create the directory, there isn’t going to be anything in it that it could use so it will ignore anything in there. You might try setting XDG_RUNTIME_DIR to something snap-specific to try to debug the issue. Eg, in a wrapper script in your snap:

XDG_RUNTIME_DIR=$SNAP_USER_COMMON <binary that tries to mkdir /run/user/0> ...

Do note that many GUI toolkits aren’t designed to run as root and under wayland this will fail outright. You might want to split out the functionality. Eg, you could create a daemon that listens on a socket that does the dmidecode on behalf of the snap. You’ll want to protect this socket in some way of course and only allow users that have proven they can sudo to be able to access the dmidecode output so in a multiuser environment your snap isn’t giving away more than it should. One way to do this would be to use a unix socket, obtain the PEERCRED of the connecting user to get the uid, then use getent group sudo to see if that user is in the sudo group.

1 Like

Creating /run/user/0/ is because I used desktop-launch in https://github.com/ubuntu/snapcraft-desktop-helpers to execute my program so it can access X11.
However I can not access X11 and hardware-observe at the same time with root permission so I changed the program not to use X11 anymore.
Right now, the snapcraft.xml is simple.

name: energy-tools
summary: Energy Tools for Energy Star and ErP Lot 3
adopt-info: energy-tools
base: core18

grade: stable
confinement: strict
license: GPL-3.0
architectures: [amd64, i386]

parts:
  energy-tools:
    source: .
    plugin: python
    parse-info: [setup.py]
    stage-packages:
      - dmidecode
      - read-edid
      - python3-debian
      - python3-xlsxwriter

apps:
  energy-tools:
    command: energy-tools
    plugs:
      - hardware-observe

But I start to encounter the file writing issue.

$ sudo energy-tools 
Energy Tools 1.6.7 for Energy Star 5/6/7/8 and ErP Lot 3
================================================================================
Which product type would you like to verify?
[1] Desktop, Integrated Desktop, and Notebook Computers
[2] Workstations
[3] Small-scale Servers
[4] Thin Clients
>> 1
--------------------------------------------------------------------------------
Which type of computer do you use?
[1] Desktop
[2] Integrated Desktop
[3] Notebook
>> 3
--------------------------------------------------------------------------------
Is there a television tuner? [y/n]
>> n
--------------------------------------------------------------------------------
Does it have switchable graphics and automated switching enabled by default?
Switchable Graphics: Functionality that allows Discrete Graphics to be disabled
when not required in favor of Integrated Graphics. [y/n]
>> n
--------------------------------------------------------------------------------
How many discrete graphics cards?
>> 0
--------------------------------------------------------------------------------
Which storage type for /sys/block/sda?
[0] Unknown
[1] 3.5" HDD
[2] 2.5" HDD
[3] Hybrid HDD/SSD
[4] SSD (including M.2 port solutions)
>> 1
--------------------------------------------------------------------------------
What is the power consumption in Off Mode?
>> 2
--------------------------------------------------------------------------------
What is the power consumption in Sleep Mode?
>> 3
--------------------------------------------------------------------------------
What is the power consumption in Long Idle Mode?
>> 4
--------------------------------------------------------------------------------
What is the power consumption in Short Idle Mode?
>> 5
--------------------------------------------------------------------------------
Energy Star 5:

  Category A: 26.28 (E_TEC) <= 44.8 (E_TEC_MAX), PASS

Energy Star 6:

  If power supplies do not meet the requirements of Power Supply Efficiency Allowance,
    30.221999999999998 (E_TEC) <= 65.3530795068758 (E_TEC_MAX), PASS
  If power supplies meet lower efficiency requirements,
    30.221999999999998 (E_TEC) <= 66.33337569947894 (E_TEC_MAX), PASS
  If power supplies meet higher efficiency requirements,
    30.221999999999998 (E_TEC) <= 67.31367189208207 (E_TEC_MAX), PASS

Energy Star 7:

    30.221999999999998 (E_TEC) <= 40.48102179154169 (E_TEC_MAX), PASS

Energy Star 8 draft 2:

  If the system doesn't meet the full Mobile Workstation definition,
    30.221999999999998 (E_TEC) <= 66.48102179154169 (E_TEC_MAX), PASS
  If the system meets the full Mobile Workstation definition,
    30.221999999999998 (E_TEC) <= 70.48102179154169 (E_TEC_MAX), PASS

ErP Lot 3 from 1 January 2016:

  Fail because P_OFF (2.0) > 0.5
  Fail because P_OFF_WOL (2.0) > 0.5
  Category A:
      26.28 (E_TEC) <= 31.8 (E_TEC_MAX), PASS
Traceback (most recent call last):
  File "/snap/energy-tools/x14/bin/energy-tools", line 36, in <module>
    core.process(description, args)
  File "/snap/energy-tools/x14/lib/python3.6/site-packages/energy_tools/core.py", line 674, in process
    sysinfo.save(profile)
  File "/snap/energy-tools/x14/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 543, in save
    with open(filename, "w") as data:
PermissionError: [Errno 13] Permission denied: 'XPS_13_9370_1.8.1.profile'

This program needs to execute with root permission to collect the hardware information however it also needs to write some output files in the filesystem at the same time.
But I can not find out any way to do it by current interfaces.

If possible, I hope you can help to approve the classic confinement request.

You don’t strictly need desktop-launch to access X, all you need is the x11 interface connected. I don’t know if you need desktop-launch for other things, but if you don’t, try not using it. If you do, try to narrow down exactly what you need and instead of using the desktop-launch wrapper, write your own.

As for writing ‘XPS_13_9370_1.8.1.profile’, you didn’t state where you were trying to write this. If run as root, then SNAP_COMMON, SNAP_DATA, SNAP_USER_COMMON (ie, in /root) and SNAP_USER_DATA (in /root) are all available to you. If the current directory and that happens to be in the $HOME of the sudoing user, then you need to write it somewhere else because, by design, we have ‘owner’ match for files in the user’s home. Also keep in mind, writing files as root in a directory that is writable by others (ie, the user’s $HOME) is not best practice (or worse), so doing something else would improve the security stance of the snap.

I can not write the file as normal user.

$ energy-tools 
Energy Tools 1.6.10 for Energy Star 5/6/7/8 and ErP Lot 3
================================================================================
Which product type would you like to verify?
[1] Desktop, Integrated Desktop, and Notebook Computers
[2] Workstations
[3] Small-scale Servers
[4] Thin Clients
>> 1
--------------------------------------------------------------------------------
Which type of computer do you use?
[1] Desktop
[2] Integrated Desktop
[3] Notebook
>> 3
--------------------------------------------------------------------------------
Is there a television tuner? [y/n]
>> n
--------------------------------------------------------------------------------
Does it have switchable graphics and automated switching enabled by default?
Switchable Graphics: Functionality that allows Discrete Graphics to be disabled
when not required in favor of Integrated Graphics. [y/n]
>> n
--------------------------------------------------------------------------------
How many discrete graphics cards?
>> 0
--------------------------------------------------------------------------------
Which storage type for /sys/block/sda?
[0] Unknown
[1] 3.5" HDD
[2] 2.5" HDD
[3] Hybrid HDD/SSD
[4] SSD (including M.2 port solutions)
>> 1
--------------------------------------------------------------------------------
What is the power consumption in Off Mode?
>> 2
--------------------------------------------------------------------------------
What is the power consumption in Sleep Mode?
>> 3
--------------------------------------------------------------------------------
What is the power consumption in Long Idle Mode?
>> 4
--------------------------------------------------------------------------------
What is the power consumption in Short Idle Mode?
>> 5
--------------------------------------------------------------------------------
Energy Star 5:

  Category A: 26.28 (E_TEC) <= 44.8 (E_TEC_MAX), PASS

Energy Star 6:

  If power supplies do not meet the requirements of Power Supply Efficiency Allowance,
    30.221999999999998 (E_TEC) <= 65.3530795068758 (E_TEC_MAX), PASS
  If power supplies meet lower efficiency requirements,
    30.221999999999998 (E_TEC) <= 66.33337569947894 (E_TEC_MAX), PASS
  If power supplies meet higher efficiency requirements,
    30.221999999999998 (E_TEC) <= 67.31367189208207 (E_TEC_MAX), PASS

Energy Star 7:

    30.221999999999998 (E_TEC) <= 40.48102179154169 (E_TEC_MAX), PASS

Energy Star 8 draft 2:

  If the system doesn't meet the full Mobile Workstation definition,
    30.221999999999998 (E_TEC) <= 66.48102179154169 (E_TEC_MAX), PASS
  If the system meets the full Mobile Workstation definition,
    30.221999999999998 (E_TEC) <= 70.48102179154169 (E_TEC_MAX), PASS

ErP Lot 3 from 1 January 2016:

  Fail because P_OFF (2.0) > 0.5
  Fail because P_OFF_WOL (2.0) > 0.5
  Category A:
      26.28 (E_TEC) <= 31.8 (E_TEC_MAX), PASS
Traceback (most recent call last):
  File "/snap/energy-tools/x5/bin/energy-tools", line 32, in <module>
    core.process(description, args)
  File "/snap/energy-tools/x5/lib/python3.6/site-packages/energy_tools/core.py", line 674, in process
    sysinfo.save(profile)
  File "/snap/energy-tools/x5/lib/python3.6/site-packages/energy_tools/sysinfo.py", line 639, in save
    with open(filename, "w") as data:
PermissionError: [Errno 13] Permission denied: 'XPS_13_9370_1.8.1.profile'