Snap refresh over metered connections

that’s exactly the information I was looking for, thank you.

Basically, the current proposal should work, especially if we make the default be to hold the refresh on known-metered connections.

Currently you can only hold refreshes for 60 days before it’ll give up and try anyway, but it sounds like that should be alright.

2 Likes

Yeah, I admit 60 day hold of refreshes is a good option. But it may not work for us. I think this proposal is a balanced solution between auto refresh vs global switch to disable auto update. Especially for us, who want the global switch for restricted data policy.

Thank you. I’m waiting for this to be available to us soon.

1 Like

Go to cafe with good WiFi.

This has now landed in master and should be available in edge channel soon. To use the feature, one needs to set:

$ snap set system refresh.metered=hold

To revert (i.e. disable holding refreshes while on metered connections) do:

$ snap set system refresh.metered=null    # or just refresh.metered=

The maximum time of holding refreshes while on metered connection is 60 days, aftere which a refresh will be attempted anyway.

Network Manager is the only supported source on information about the default connection being metered at the moment.

3 Likes

Amazing thank you! :blush:

How does this stack with the refresh timer? Is a refresh attempted immediately after the 60 days regardless of what the timer is set to or will it refresh when the timer has set refreshes? What’s the cooldown period after the 60 days? If it’s set to null after 60 days and then set back to hold, are refreshes held for another 60 days? What happens if I changed it to null and immediately back to hold after 59 days? Does that reset the countdown? Or is this info not public (in which case I guess someone could deduce the answer by checking the code?) :slight_smile:

It’s checked against the time of last refresh. Basically, if you are on metered and last refresh was more than 60 days ago, the refresh can proceed.

1 Like

Going back to the GNOME 3.28 feature, does toggling there also automatically toggle the snapd setting or is that a bug that I need to file (against snapd or GNOME)? :slight_smile:

1 Like

We don’t look at any gnome settings so I suspect some integration is in order

1 Like

Likely not, as that seems to be a NetworkManager frontend for the aforementioned metered connection manual override.

I believe snapd should enable the metered connection detection by default in the future without one to manually set the feature.

1 Like

Flatpak has their automatic updates automatically disabled on metered connections (4th heading), hopefully snappy can catch up (sorry that I have not been able to help) :slight_smile:

3 Likes

Testing steps

Basic run through

Enable holding refreshes when on a metered connection:

$ snap set system refresh.metered=hold

Check if your connection is considered to be metered by NetworkManager. First determine the name of active connection:

$ nmcli c show --active
NAME     UUID                                  TYPE  DEVICE
G6_3577  31517f2b-25e7-4189-ab95-6d01f1482a67  wifi  wlp3s0

The host is connected to network G6_3577 which a hotspot on my phone. Check the human readable status (can be yes, no, unknown):

$ nmcli c show 'G6_3577' | grep connection.metered
connection.metered:                     unknown

If the status is unknown, try to determine the exact status reported by NetworkManager:

$ busctl --system get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered
u 3

NetworkManager reported status code 3. Refer to the list of status codes reported by NetworkManager:

NM_METERED_UNKNOWN = 0    The metered status is unknown
NM_METERED_YES = 1        Metered, the value was statically set
NM_METERED_NO = 2         Not metered, the value was statically set
NM_METERED_GUESS_YES = 3  Metered, the value was guessed
NM_METERED_GUESS_NO = 4   Not metered, the value was guessed

Status code 3 is NM_METERED_GUESS_YES. Only status codes 1 (NM_METERED_YES) and 3 (NM_METERED_GUESS_YES) will make snapd hold refreshes.

Leave it at that and wait for refresh to kick in. You should observe the following in snapd logs:

Sep 07 13:13:10 corsair snapd[8854]: autorefresh.go:186: DEBUG: Auto refresh disabled on metered connections
Sep 07 13:18:10 corsair snapd[8854]: autorefresh.go:255: DEBUG: Next refresh scheduled for 2018-09-07 13:18:10.159430386 +0200 CEST m=+1200.109631500.
Sep 07 13:18:10 corsair snapd[8854]: autorefresh.go:186: DEBUG: Auto refresh disabled on metered connections
...

My connection is not metered but should be

You can make NetworkManger mark any connection as metered using either command line or the graphical tools (eg. GNOME’s network settings).

Assume I have a network connection named wireless 5.8. NetworkManager did not correctly find out that the connection is metered.

$ nmcli c show --active
NAME            UUID                                  TYPE  DEVICE 
wireless 5.8    227b1939-f7c6-4769-8ac0-7393936eb1d3  wifi  wlp3s0 
$ nmcli c show 'wireless 5.8' |grep connection.metered
connection.metered:                     unknown
$ busctl --system get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered
u 4

Reported status code is 4 (NM_METERED_GUESS_NO).

The CLI way

Modify connection properties and mark it as metered:

$ nmcli c modify 'wireless 5.8' connection.metered true

Double check the reported status:

$ nmcli c show 'wireless 5.8' |grep connection.metered       
connection.metered:                     yes
$ busctl --system get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered
u 1

Reported status is 1 (NM_METERED_YES).

The GUI way

Head to GNOME network settings:

https://i.imgur.com/AimSeWM.png

Select your currently connected network settings:

https://i.imgur.com/nvcEany.png

And tick Restrict background data usage, then Apply.

Double check the reported status:

$ nmcli c show 'wireless 5.8' |grep connection.metered       
connection.metered:                     yes
$ busctl --system get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered
u 1

Reported status is 1 (NM_METERED_YES).

2 Likes

Can snap set system refresh.metered=hold be the default in future releases of snapd please (assuming this works well enough) so that updates are held back by default on metered connections rather than allowed by default?

1 Like

It’s up for review already:

2 Likes

wait, does that mean I won’t get my updates any more once a future release lands on my box?

I would suggest that to be rather unexpected considering all the marketing touts updates to snaps being delivered automatically.

if your only network connection is a 3/4G/LTE modem thats probably true

1 Like

If you’re on metered connection all the time, the updates will be postponed for up to 60 days max. After that we’ll update anyway.

1 Like

@mborzecki please note that the settings that nmcli shows do not really reflect the value for the Metered DBus property of the device. The former are static and stored in a file, while the property is dynamic. For a modem connection in a system I can access:

$ nmcli c show verizon | grep metered
connection.metered:                     unknown

But the property for the device shows:

$ dbus-send --system --print-reply --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager/Devices/5 org.freedesktop.DBus.Properties.GetAll string:"org.freedesktop.NetworkManager.Device"
...
      dict entry(
         string "Metered"
         variant             uint32 3
      )
...

Also, I see that you are checking org.freedesktop.NetworkManager.Metered, which shows the Metered property of the principal device, so be careful with that.

The conclusion is that all modems have NM_METERED_GUESS_YES by default, which can have consequences for backwards compatibility. If snapd is going to add this new setting, this needs to be taken into account.

We’re looking at the top level NM property of the manager itself. IIRC this is a sort-of an aggregate value taking into consideration the current default route.

This should get you the value we use for deciding whether the host is metered or not.

busctl --system get-property org.freedesktop.NetworkManager \
/org/freedesktop/NetworkManager org.freedesktop.NetworkManager Metered

It looks like NM_METERED_YES is never set by NM unless explicitly instructed by a user to do so. In that sense, this change would be safe if snapd only stops the automatic updates if org.freedesktop.NetworkManager.Metered is NM_METERED_YES in NM (regardless of whether this had been set from snapd or by the user).

snapd uses bot NM_METERED_YES and NM_METERED_GUESS_YES, see here for details:

We want to stay with the logic as it’s an automatic win for people who roam.

I guess the gist of the problem is determining whether there are Ubuntu Core devices, using NM, which have their default route through a modem connection (i.e. modem is the main connection). In such case, the current code would hold refreshing the snaps for up to 60 days what may be undesired and so we need to find a way to use a different default.