Disallow mixing try and non-try snap installs

Currently a user can snap install foo, getting the snap from the store, and then snap try foo/ and have the snap be in “trymode”:

~/src/httpie-snap/stage$ sudo snap install http
http 0.9.6-0 from 'chipaca' installed
~/src/httpie-snap/stage$ sudo snap try
http 0.9.6-0 mounted from /home/john/src/httpie-snap/stage

it does not end well:

~/src/httpie-snap/stage$ snap list http --all
Name  Version  Rev  Developer  Notes
http  0.9.6-0  19   chipaca    disabled,try
http  0.9.6-0  x1              try

note how trymode applies to the whole snap. This is because in the state the flag is stored at the snap level, and not in the sequence. Fortunately snapd doesn’t use the flag other than for informative purposes (a snap revert http drops the flag), but I’m pretty sure this whole area is an untested corner case.

It gets worse: we’re going to need to store the original directory used for snap try, to detect at runtime whether the directory (still exists and) is encrypted; if we don’t store this in the state we’d need to go look at the mount unit, which feels like the wrong approach. If we store it in the sequence we now need to either use a new Info-like struct as the Sequence, or add SnapPath to SnapInfo, neither of which is really palatable as things stand.

So, I propose we block mixing try and non-try snap installs. If a snap is installed and you snap try it, you get told to remove it first (and viceversa). This way the current TryMode flag in state is correct, and we can store SnapPath next to it and it still makes sense. A use case for mixing try and non-try is to try out migrations, which if we want to support we could add an explicit flag to try so it copies data before removing the old non-try snap.

Thoughts?

I think we should store the original directory (because it feels useful) but we also must store the flag that indicates if it was encrypted at the time try was issued. The problem is that snapd may be asked to re-generate the apparmor profile at any time, including when the encrypted home directory is not yet mounted, and the fact encryption may be required is an input to the apparmor backend. (CC @jdstrand)

I agree that we need to store it in the sequence (or a similar sequence-like object to avoid patch issues).

When a snap is installed via snap try, if the directory goes away the snap should uninstall. This includes the mountpoint going away because it was encrypted and the user logged out (or rebooted and hasn’t yet logged in).

Whether the directory is encrypted or not is something that can change behind snapd’s back, ie the user can switch to have an encrypted home by taking the system offline and fiddling with it (and conversely they can switch it to non-encrypted). Whether the directory is encrypted, then, needs detecting at runtime when we need the information.

Unless what you’re saying is that the behaviour of removing the snap when the directory goes away is different whether the directory was encrypted or not?

What about the (typical case) when directory exists but only when the user is logged in?

EDIT: I’m arguing that this is a pretty unexpected outcome. I snap try something, I reboot / log out and my snap (and data) is gone? That’s a bug IMO.

that’s only the typical case when you have an encrypted home.

Encrypted home is an option you can enable during installation of Ubuntu for a few years (and I bet other distributions are no different). While I have no statistics I’m sure it’s not uncommon to have this on a laptop.

I was wrong about the current behaviour of snapd being to remove a tryed snap if the directory goes away. It enters broken state, instead, and recovers once the mount comes back.

Just wanted to put my two cents in regarding disallowing this.

I have two snaps that I use every single day. rocketchat-desktop and openwmail. But of which I often have to do some tweaking to the snap and do a try make sure everything works and then revert it back to the last revision and publish to the store.

What you’re proposing seems like it would make it so I would have to remove my snap before I could try the new build? Am I understanding correctly?

when you say “before I could try the new build”, do you actually mean using snap try, or do you snap install the newly built .snap file?

Wasn’t the feature of being ephemeral a good thing for try? Better messaging from the UI would solve these problems for me.

Also, when you say store the directory, you mean just the path and not the contents, right?

By try the new build I mean I would do something like this:

  1. Make changes to snapcraft.yaml
  2. run snapcraft
  3. sudo snap try prime/
  4. Verify everything good
  5. sudo snap revert snap-name (possibly sudo snap revert snap-name --revision x if I had done a try multiple times).
  6. Publish updated snap

This is great because I have files stored in the home folder. It creates an x1 x2 etc folder and if anything breaks here… no biggie I can revert. But its using real data. So i’m able to try things like migrations and etc. Just as it would be when I publish the snap.

Downside of course is if you do snap try too many times in a row… snapd helpfully gets rid of the old stable revision… and can lead to me having to cp ~/snap/snap-name/current and then restoring after removing and installing the snap again.

To me being able to try a snap I already have installed is part of my flow. If I had to actually remove my snap first… it would lead to me and i’m assuming other developers facing more irritation with the dev -> iterate -> repeat cycle.

1 Like

Thank you, this is very valuable feedback.

No problem :slight_smile:

I might be doing things completely against how designed/intended… :blush: If there is a better way. I’d definitely be open to checking it out. I just want to avoid having to remove the snap and loose the data I use every day.

Like the rocketchat-desktop snap. I’m using it all day every day, i’ve got a lot of data in there. So any time i’ve got to do an uninstall/install switcharoo just for dev… this is a huge headache.