Share installed snaps between devices?

I work in an internet-poor area, and my goal is to develop a way to share updates from one system to another without having to go online and download the snap + assert files again.

Is it possible to share an installed snap without re-downloading it? I know I can get the assert and snap files by $ snap download [snap-name], but what about directly sharing an already-installed snap from one machine to another?

I know how to find the snap file itself on my system in /var/lib/snapd/snaps/, but what about the assert file? I think all the info normally in an assert file is findable on my system, so I could in theory re-create it, but I’d rather have a more “sanctioned” and fool-proof way to do it.

3 Likes

It would be nice if there was a dedicated snap something command to do this, but you can get assertions from the system (only outside of snap confinement, i.e. not from inside a snap unfortunately unless you plug snapd-control, which we don’t allow publishing to the store) by using the REST API.

For example, you could get all snap-revision assertions this way:

curl --unix-socket /run/snapd.socket http://localhost/v2/assertions/snap-revision?authority-id=canonical

And then you’d get all auto-connect assertions, etc. and manually build up the .assert file that is downloaded with snap download, but this would be a fair amount of work.

1 Like

What is snap known snap-revision?

You can get the assertions using snap known, and then load them with snap ack. It’s a bit fiddly but doable.

Alternatively, install the snaps with --dangerous, and then use snap refresh --amend to have snapd figure the assertions out itself.

I guess I wasn’t aware you could use snap known like that, but still it is only a piece of the puzzle, as you can’t build up the full .assert file from just snap known snap-revision. I was looking for more something like

snap build-assert-file snap-name snap-revision
<< spits out the exact same content of the .assert file >>

As I say, using it for this is fiddly (but note your curl command was only looking at snap-revision, hence my quip).

You’d need something like

GO_FLAGS_COMPLETION=1 snap known "" | xargs -n1 snap known > all.assert

I too would like to see a snap known --for-snap-files=foo.snap,bar.snap. But, ultimately, what we want to do is have snap download talk to the local snapd and figure things out from there.

I didn’t know about the $ snap known command. As you said, it’s a bit fiddly, but I was otherwise resorting to a shell script with judicious use of sed and grep to gather this info. This simplifies that part of the process, but the correct information still has to be assembled into a new .assert file. I
would be very happy to have a more straightforward command for this.

Depending on how your devices are networked, you may be able to set up a snap store proxy. This doesn’t answer your original question but it might solve the same problem.

1 Like

Yeah, I looked into that. We’re a low-budget operation in the developing world with frequent random power outages (rather, I should say, typically no power with the occasional random availability of power) and a very slow internet connection (typically under 1Mbps for an office of 30+ people). So, we really need a low-tech solution.

I have a script I’m starting to test now that seems to do what I need, but it still needs some further testing.

If at some point you feel comfortable sharing the script, I’d be more than happy to, at least,

  1. peer-review it
  2. add it to our integration suite so we don’t break your use case
  3. feed this use case back to our teams so we can think of ways to improve it in the longer term

thank you!

I appreciate your offer of help. My primary question I haven’t figured out yet is whether running $ snap ack < assert >; $ snap install < snap > on a snap with a higher revision than the one installed is effectively the same as running $ snap refresh < snap > to the snap store. That seems to be the case to me (see my other post for more info: Explanation of "refresh" vs "install" of a new revision of an installed snap?), but I haven’t tested enough yet to be sure. But my script is based on this premise.

Oops, I forgot to answer on that one. The short answer, as I said there, is that if they are materially different it’s a bug.

One thing that I mention there is assertions refresh, which might be worth exploring once we have a clear picture of what you’re trying to do.

One thing we might need to look into is supporting --epoch on snap download…

We’re not in a completely offline situation here, so it might be that we would “typically” do an initial snap install with the already-downloaded snap and assert files to save data usage, then let the system go online to get it automatically refreshed to the current version. But there are some people who may prefer to have complete control of their data usage, which would mean maybe setting the system timer for a narrow window when they’re likely to be offline anyway to effectively kill the automatic refresh process (I haven’t actually tried to put this into action yet). I know that’s contrary to the ethos of snaps, but it’s the reality of our situation.

And it’s for that kind of situation (or where they normally work in their village with zero internet) that I’m preparing this script.