MongoDB snap

Hi, I’m new to snapcraft and I’m trying to create a MongoDB snap with the latest version.
I’ve been reading through the tutorials and documentation and used this github as a start.

My changes:

  • Updated the version
  • Changed the download link
  • Added a base
  • Moved the plugins to snap/plugins

The error i’m getting:

Source path "/ssd/dev/snaps-niemeyer/mongodb/mongo42" does not exist
An error occurred with the instance when trying to mount with 'multipass': returned exit code 1.
Ensure that 'multipass' is setup correctly and try again.

Any help would be appreciated.

The snapcraft.yaml:

name: mongo42
version: 4.2.8
summary: MongoDB document-oriented database

description: |
    MongoDB is a high-performance, open source, schema-free
    document-oriented data store that's easy to deploy, manage
    and use. It's network accessible, written in C++ and offers
    the following features:

       * Collection oriented storage - easy storage of object-style data
       * Full index support, including on inner objects
       * Query profiling
       * Replication and fail-over support
       * Efficient storage of binary data including large objects (e.g. videos)
       * Auto-sharding for cloud-level scalability

    High performance, scalability, and reasonable depth of functionality
    are the goals for the project.

base: core18
grade: devel
confinement: devmode

apps:
    mongo42:
        command: bin/run.sh mongo

    mongod:
        command: bin/run.sh mongod --port=33017 --smallfiles --noprealloc
        daemon: simple

    d:
        command: bin/run.sh mongod
    s:
        command: bin/run.sh mongos

    export:
        command: bin/run.sh mongoexport
    import:
        command: bin/run.sh mongoimport
    dump:
        command: bin/run.sh mongodump
    restore:
        command: bin/run.sh mongorestore

    top:
        command: bin/run.sh mongotop
    stat:
        command: bin/run.sh mongostat
    perf:
        command: bin/run.sh mongoperf

    files:
        command: bin/run.sh mongofiles
    sniff:
        command: bin/run.sh mongosniff
    oplog:
        command: bin/run.sh mongooplog

plugs:
    home:
    network:
    network-bind:

parts:
    mongodb:
#        source: https://fastdl.mongodb.org/linux/mongodb-linux-aarch64-ubuntu1804-4.2.8.tgz
        source: https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-4.2.8.tgz
        plugin: dump
        stage-packages:
#            - libc6 leads to warning "libc6 has been staged into the snap: only do this if you know what what you are doing." and a segfault when running
            - libssl1.1

    content:
        source: ../content
        plugin: dump

Multipass (the system that operates the Virtual Machines for Snapcraft) is strictly-confined, which means that it can only access specific locations on your filesystem. According to snap connections multipass the only available interface for filesystem allowance is home which grants permission for multipass to read files in /home/$USER/* (excluding /home/$USER/.* - i.e. files and folders in your home folder that begin with a dot/period: .) It does include multipass-support which might grant further filesystem locations, but I’m not sure if or what those are.

Ideally multipass should also include the removable-media plug, which allows access to filesystems at /media/$USER/* and GVFS-mounted filesystems on a desktop at /run/user/$UID/gvfs/*, but this appears to not be the case, currently. I’m not sure who to ping to get that added, so I’ll ping my favourite pingee @popey because he’s awesome and knows all ;-p

I thought the plug “home” would fix the permission.

Regarding the GLIBC error, I just got a hint while messing around: The linker version '2.23' used by the base 'core' is incompatible with files in this snap:

Guess it’s not about the libc.so on my system, but about the one used by the base?

The core* bases are build from respective Ubuntu releases. The core is basd on Ubuntu 16.04, core18 is Ubuntu 18.04, core20 is Ubuntu 20.04. Looking at the prebuilt mongdb URL you used which is
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1804-4.2.8.tgz I would guess the binary was built on Ubuntu 18.04, meaning you need to use core18.

Hey, thanks for the reply.

I guessed that when removing base: core18 , it was using ubuntu 16 indeed, leading to the libc error. I updated my first post.

I’m still stuck however, at the error Source path "/ssd/dev/snaps-niemeyer/mongodb/mongo42" does not exist. I don’t know what is trying to access that. Does it have anything to do with how the dump.py or run.sh is made?

I think multipass (which is a strictly confined snap now), is unable to access /ssd/dev/snaps-niemeyer/mongodb/mongo42. Since /ssd/dev/ is just some random path in your system, snap do not know whether it contains sensitive data and if so, what data, or whether any interface should allow accessing it, so it is not available in the filesystem view that multipass can observe.

That being said, multipass, plugs the home interface as @daniel indicated (see docs here). Moving the source tree to your $HOME and building from that location should make it work.

Ah, now I get it. I completely forgot that multipass itself is a snap. Shame though, as my home dir isn’t on an sdd. But thanks a lot, will give it a try!

Great! Once I moved it to my home dir, it managed to get passed the “path does not exist” error.

Of course, the content dir is the next error on the menu: Failed to pull source: unable to determine source type of '../content'.

I’d guess snapcraft has only set up multipass to access the directory tree with root at where snapcraft.yaml is. However, snapcraft.yaml references ../content which is a level up. You probably need to tweak the file to make it do what you want and how you build it.

Another step ahead :slight_smile: Moving the content dir to where the yaml is located, did the job.

What is the normal way of adding binaries like that?

Creating the snap now finishes, but when running it, i get the error:
/snap/mongo42/x3/bin/mongo: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory

Searching for that file gives me:

$ locate libcurl.so.4
/snap/mongo42/x2/usr/lib/x86_64-linux-gnu/libcurl.so.4
/usr/lib/x86_64-linux-gnu/libcurl.so.4
/usr/lib/x86_64-linux-gnu/libcurl.so.4.5.0

What is this “x2” vs “x3” ?

x[0-9]+ is the automatically assigned local revision when you install the snap from file.

I would expect snapcraft to pick up libcurl.so.4.5.0 automatically, but maybe you need to add libcurl to stage-packages manually.

Ah, makes sense, thanks.

Added libcurl4, brings me a step further again :stuck_out_tongue:

Did get a warning now though:

Pulling mongodb 
Downloading 'mongodb-linux-x86_64-ubuntu1804-4.2.8.tgz'[==============================================================================================================================================] 100%
Building content 
Building mongodb 
Staging content 
Staging mongodb 
Priming content 
Priming mongodb 
This part is missing libraries that cannot be satisfied with any available stage-packages known to snapcraft:
- libpcap.so.0.8
These dependencies can be satisfied via additional parts or content sharing. Consider validating configured filesets if this dependency was built.
A shell wrapper will be generated for command 'bin/run.sh mongod --port=33017 --smallfiles --noprealloc' as it does not conform with the command pattern expected by the runtime. Commands must be relative to the prime directory and can only consist of alphanumeric characters, spaces, and the following special characters: / . _ # : $ -
Snapping |                                                                                                                                                                                       
Snapped mongo42_4.2.8_amd64.snap

And running it gives me a connection error, which I guess is caused by some missing interfaces?

$ mongo42
MongoDB shell version v4.2.8
connecting to: mongodb://127.0.0.1:42017/?compressors=disabled&gssapiServiceName=mongodb
2020-07-27T13:53:55.669+0200 E  QUERY    [js] Error: couldn't connect to server 127.0.0.1:42017, connection attempt failed: SocketException: Error connecting to 127.0.0.1:42017 :: caused by :: Connection refused :
connect@src/mongo/shell/mongo.js:341:17
@(connect):2:6
2020-07-27T13:53:55.670+0200 F  -        [main] exception: connect failed
2020-07-27T13:53:55.670+0200 E  -        [main] exiting with code 1

Aren’t you trying to run a client?

No, i need the server. It’s for an ubuntu core image that I want to make.

Ok, so you want to run mongo42.mongod then.

Aha, was comparing to the original mongo33, which did run without issue.

$ ps aux | grep mongo
root  1256  0.6  0.2 272628 34300 ?        Ssl  08:35   2:26 /snap/mongo33/x1/bin/mongod --dbpath=/var/snap/mongo33/x1/../common --port=33017 --smallfiles --noprealloc
bart  30973  2.0  0.6 1580680 106276 pts/1  Sl+  15:00   0:01 /snap/mongo42/x5/bin/mongod --dbpath=/home/bart/snap/mongo42/x5/../common --port=42017
bart  31066  0.9  0.2 1235532 43724 pts/0   SLl+ 15:00   0:00 /snap/mongo42/x5/bin/mongo --port=42017

Looks like mongo33 automatically started up mongod.