Trying to convert Enpass to a Snap

Hello everyone and Merry Christmas!

I just started my adventure in the world of snap development and I’m trying to convert one of the few apps that I use and are missing from the Snap Store. After reading through the starter documentation and the Docs section in general, I have a few things that aren’t quite clear.

First off, I should explain what Enpass is. It’s my password manager of choice, it’s closed source so it comes in precompiled DEB and RPM packages by default. You can find the installation info here.

So far, my snapcraft.yaml looks like this:

name: enpass 
base: core18
version: '6.5.1.723'
summary: Unofficial Snap for the Enpass Password Manager
description: Offline Password Manager and Secure Vault. Saves and fill in all your passwords, cards and other details. Free for Mac, Windows and Linux.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: classic # use 'strict' once you have the right plugs and slots

apps:
  enpass:
    command: opt/enpass/Enpass
    
parts:
  enpass-deb:
    plugin: dump
    source: "https://apt.enpass.io/pool/main/e/enpass/enpass_$SNAPCRAFT_PROJECT_VERSION_amd64.deb"
    source-type: deb
    stage-packages:
      - libxss1
      - libcups2
      - libfreetype6
      - libpng16-16
      - libgl1-mesa-glx
      - libice6
      - libsm6
      - libx11-xcb1
      - libxrender1
      - libfontconfig1
      - libgtk-3-0
      - libpango-1.0-0
      - libpulse0
      - libxcb-glx0
      - libxkbcommon-x11-0
      - libxkbcommon0

However I do have a couple of problems that I am quite confused about:

  1. Should I be starting off with the deb package, rpm package or anything else? The documentation on the plugins was a little unclear as I couldn’t originally figure out originally that I should be using dump, even though I had a deb file. Also, I’m thinking about automating this in the future, so I would like to know what’s the best way to track updates to the official repositories.
    If there’s an example from another Snapcrafter’s project that’s also precompiled, that would be really helpful. The only one that I found was Discord but they have direct downloads on their website and I couldn’t figure out where the script was that tracked the changes.

  2. What are the differences between classic and devmode? I think I understand the differences outlined here but by that logic classic confinement should be more confined than devmode, correct? I’m asking since this is how my app looks in devmode:
    image
    Where as in classic mode, the text is properly rendered.
    There are other differences as well, such as the fact that classic mode launches any links in its own Firefox profile whereas devmode uses the already existing one.

  3. Is it correct that I am including so many stage packages? I followed the automatic dependency resolution that I got after running snapcraft where it reported there were number of missing so files, so I tracked each dependency down. Should I be using plugs instead?

There’s still lots more to do and I’m learning as I go so, please, if you have any feedback, I would love to hear it! I’m still a complete noob when it comes to packaging applications, so I might be missing something extremely obvious.

Thanks for reading through all my text! Any and all feedback would be appreciated.
-Chris

Re 1:
There’s no real right way to start off. The app is closed source so you can’t build it, so extracting it from somewhere else is nearly essential. The dump plugin is usually the best plugin for this, and the .deb format comes with some clear advantages for convienience.

You can track the upstream deb in the repository better by actually adding the repository into the build environment. This is currently still experimental functionality, but take a look here https://snapcraft.io/docs/package-repositories because it can still actually be used by passing it a parameter, works well, and is expected to be available generally fairly soon.

Re 2)
Both classic and devmode snaps are under less sandboxing than strict snaps, but a devmode snap has the eventual goal of becoming a strict snap. A classic mode snap doesn’t usually have the goal of becoming a strict snap, and is classic because it almost philosophically cannot become a strict snap.

Practically, your font problem makes a good example. The classic mode works because classic mode integrates more traditionally with the system, it can use without any extra setup the fonts from the host system, and access all the areas it’s expected to be able to access. When you say it’s a devmode snap rather than classic, it’s $PATH value is changed, it get’s blocked off from the usual routes of accessing font caches, and its root directory is rewritten to be consistent from machine to machine, so /usr/bin in a devmode snap and /usr/bin in a classic snap are actually two entirely different folders and don’t contain the same files.

You have to do some special work to get fonts to work consistently, add the Gnome extensions and they’ll do it for you, including defining some default interfaces and other work not related to fonts (Pulseaudio, keyboard input, themes, etc). https://snapcraft.io/docs/snapcraft-extensions

An extension works by transforming your snapcraft.yaml before it gets built, you can run snapcraft expand-extensions to see what it effectively gets rewritten to, and you’ll notice it’ll add X11 and Wayland interfaces and such for you by default.

apps:
  enpass:
    command: opt/enpass/Enpass
    extensions: [gnome-3-34]

Re 3)
You could use plugs if they make sense (The gnome extension above will automatically use some plugs and add some of its own stage packages for you), but there’s a lot of caveats to it and I wouldn’t focus on it for the time being. It’s not wrong to have too many stage packages, it’s just preferable to not make the snap bigger if you can avoid it. The method of letting Snapcraft identify the packages itself is a good method to use. Do keep in mind length of the list isn’t necessarily bad, one big meta package that contains a thousand other packages isn’t better just because the list is shorter, it might inflate the snap more than having the packages specified more granually.

1 Like

Excellent, thank you so much for the response! This is really helpful, I’ll try to make the changes and I’ll report back with my progress.

Glad to help!

I just notice you asked for an example of using a deb from a repo automatically. I’ve one here for you that uses the experimental package repositories. The Mono repo is added and the Pinta PPA is added. Pinta then has Mono listed as a dependency, so the newest version of both gets used.

1 Like

Don’t forget to check that the license permits you to create copies and distribute those copies to third users. If they have a no-redistribution clause then you cannot legally put the deb inside a Snap Package, but must download it the first time the user runs your snap.

1 Like

I’m afraid you are correct! Their ToS seems to state that I cannot redistribute the software, although it mostly focuses on the premium versions which are an in-app purchase.

https://www.enpass.io/terms-of-use/

Found under " 6. Limited Right to Use". That’s unfortunate, given how it complicates manners and it makes archiving the software if the official repos go down even trickier. Should I make an effort to contact the developers through their forums? As far as I am aware, they are open to the idea of Snaps and Flatpaks, as seen here:

https://discussion.enpass.io/index.php?/topic/8076-linux-make-an-official-enpass-appimagesnapflatpak/&do=findComment&comment=30716

Either way, I think I’m going to continue privately like this for now and then figure out how to download it on the fly once I’ve got everything fully working.

Thought I should give you an update on the status of my snap so far! This is what my snap.yml looks like right now:

name: enpass
base: core18
version: '6.5.1.723'
summary: Unofficial Snap for the Enpass Password Manager
description: Offline Password Manager and Secure Vault. Saves and fill in all your passwords, cards and other details. Free for Mac, Windows and Linux.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
  enpass:
    command: opt/enpass/Enpass
    desktop: usr/share/applications/enpass.desktop
    extensions: [gnome-3-34]
    
parts:
  enpass-deb:
    plugin: dump
    source: "https://apt.enpass.io/pool/main/e/enpass/enpass_$SNAPCRAFT_PROJECT_VERSION_amd64.deb"
    source-type: deb
    stage-packages:
      - libxss1
      - libxkbcommon-x11-0
    override-prime: |
      snapcraftctl prime
      sed -i 's|Icon=.*|Icon=${SNAP}/meta/gui/enpass.svg|g' $SNAPCRAFT_PRIME/usr/share/applications/enpass.desktop
  snap-gui-folder:
    plugin: dump
    source: gui/
    organize:
      enpass.svg: meta/gui/

For the most part, the app now works in devmode, as including the Gnome 3.34 Extension fixed most of the issues. However there are still a few things that I can’t quite understand and still have to work on:

  1. This is a Qt application. However, when using the kde-neon extension that is recommended for Qt apps, I was getting lots of issues and the fonts weren’t rendering. Is that normal? Is it fine that I’m using gnome-3-34 instead?

  2. I had some trouble with the icon of desktop shortcut which I got around to integrating. It seems that I am affected by the following bug:

For now, I have instead included an SVG icon from Enpass’s press kit, found here. However, I would like to eventually use the NxN icons found inside the deb package to reduce the amount of extra things needed.

  1. There are a few issues that I’m not sure I can fix without asking the developers to make changes to their app. This is what I’m most concerned about. For example, the command shown that’s recommended for the shortcut will work for this version but will break with every update:
    image

I’ve also been having some issues getting the Firefox extension to play nicely. It launches the app and almost works, but it doesn’t seem to be communicating right as it says it couldn’t find the app. I’m not sure what the issue is yet.

Finally, I still have to look into AppArmor violations and how to make the app work in strict mode. I also have to download the deb file during installation, and I haven’t looked into that either .

I guess things are going ok! Thanks for the help so far, I’ll report back when I get more things working. In the meantime, if you have any thoughts or suggestions, let me know!

Sorry for a bit of a necro, but I thought I should offer some closure. After contacting the Enpass developers, they were very helpful and gave me explicit permission to redistribute Enpass on the Snap Store! They’re also helping me fix the two final issues: the System-wide Hotkey and Browser Autofill. The browser autofill especially is quite tricky, so let’s hope they can figure it out!

Link to the Snap Page:

Link to the Enpass Forum Discussion:
https://discussion.enpass.io/index.php?/topic/26412-adding-enpass-to-the-snap-store-with-your-help/

Thanks everyone for your help! My first experience with publishing snaps has been extremely positive. From the detailed docs to the many helpful people who stepped in on the forum, I’ve had a lot of help! I hope I can continue to contribute to the store!

3 Likes