Creating a snap of a bash script with multiple files


#1

Hello,

I’m new to snaps.

I’ve written a bash script that executes a ruby script and I’m having trouble packaging it as a snap.

The image below shows my project folder:
snap_files

My project essentially has three files:
movies.sh
functions.sh
html_parser.ruby

movies.sh requires the other two files.

I don’t understand what I need to put in the snap.yaml file so that when I run snapcraft my snap will install and I’ll be able to execute it. Can somebody help? or perhaps show me a similar example?


#2

You will need to add ruby to stage-packages in addition to any ruby modules you require:

name: mymovies
summary: movies thingy
description: >
  movies long description....
version: '0.0.1'

grade: stable
confinement: strict

parts:
  movies:
    source: .
    plugin: dump
    stage-packages:
    - ruby
    - a-ruby-module-package # just an example. either remove or change to a real package name

apps:
  mymovies:
    command: movies.sh
    plugs:
    - home # if you want to access your home folder?
    # ... any other plugs required for your script ...

#3

Hi Daniel,

Thank you for the quick reply! The snap.yaml file you provided was very useful.

I tried to run snapcraft and I was instructed to add libc6 as a stage-package requirement. I then ran snapcraft with the libc6 package added to the snap.yaml file and it created the snap file (mymovies_0.0.1_amd64.snap).

I typed sudo snap install mymovies_0.0.1_amd64.snap --dangerous and it installed the snap. When I run the snap by typing mymovies I get the error: “Segmentation fault (core dumped)” - Do you know what could be causing this error?

Also, there are three requirements for my ruby script that I’m not sure how to install. I installed them on my computer using gem. The gems are nokogiri, xpath and csv. Is there a way to put gems as a required package with snap? How should I handle this?

My snap.yaml file is below:

name: mymovies
summary: movies thingy
description: >
movies long description…
version: ‘0.0.1’

grade: stable
confinement: strict

parts:
movies:
source: .
plugin: dump
stage-packages:
- ruby # just an example. either remove or change to a real package name
- libc6

apps:
mymovies:
command: movies.sh
plugs:
- home # if you want to access your home folder?
# … any other plugs required for your script …


#4

For nokogiri and xpath these are available as debian packages, so you can add ruby-nokogiri and ruby-xpath as additional stage-packages. For csv you will need to do some tweaking. The easiest way to get it added is to add an override to the build script with:

parts:
  movies:
    source: .
    plugin: dump
    build-packages:
    - ruby-dev
    override-build: |
      gem install csv -i $SNAPCRAFT_PART_INSTALL
    # ... the rest of the part ...

You will need to also adjust your app definition to include a pair of environment variables:

apps:
  mymovies:
    command: movies.sh
    environment:
      GEM_HOME: $SNAP/gems
      GEM_PATH: $SNAP
    # plugs ...

You might also need to define the RUBYLIB environment variable per https://docs.snapcraft.io/build-snaps/ruby which has some good documentation on ruby support in snapcraft.


#5

Daniel,

Thanks for the reply.

I’ve taken a look at https://docs.snapcraft.io/build-snaps/ruby and added the following to my snap.yaml file:

  • Added build-packages: [gcc, libc6-dev, make, ruby-dev] to parts
  • Added RUBYLIB: $SNAP/usr/lib/ruby/2.3.0:$SNAP/usr/lib/x86_64-linux-gnu/ruby/2.3.0 to apps / environment

However, I’m getting the error below about snap metadata:

What do you think? My snap.yaml file is below:

name: mymovies
summary: A script to obtain information about movies playing in your area
description:
movies long description…
version: ‘0.0.1’
<
grade: stable
confinement: strict
<
parts:
movies:
source: .
plugin: dump
build-packages: [gcc, libc6-dev, make, ruby-dev]
override-build: |
gem install csv -i $SNAPCRAFT_PART_INSTALL
stage-packages:
- ruby # Deb packages can go here
- libc6
- ruby-nokogiri
- ruby-xpath
<
apps:
mymovies:
command: movies.sh
environment:
RUBYLIB: $SNAP/usr/lib/ruby/2.3.0:$SNAP/usr/lib/x86_64-linux-gnu/ruby/2.3.0
GEM_HOME: $SNAP/gems
GEM_PATH: $SNAP
plugs:
- home # if you want to access your home folder?
# … any other plugs required for your script …


#6

That error indicates that movies.sh either does not exist in the snap, or is not in the root directory of the snap. If you’re building locally without using cleanbuild then you can investigate the prime/ folder from your project tree to determine whether the file made it into the snap and whereabouts it got placed. The prime/ folder is used as the root of the snap, so when you specify movies.sh that is equivalent to prime/movies.sh. Likewise if you specify the command as bin/movies.sh then that translates to prime/bin/movies.sh when you’re investigating.

Once you find the file get the full path and remove everything from the beginning up-to, and including, the word “prime” and the slash after “prime”. This will then be the snap-local path to the file for putting in the command: parameter.


#7

Hi Daniel,

I’m not sure I understand. I’ve installed LXD and I’ve been running snapcraft cleanbuild:

But, the priming fails:

My YAML file is below:

I don’t understand what is wrong with the path. I checked my local snapcraft attempt and movies.sh wasn’t in the prime folder. I’ve since run snapcraft clean and i’m now trying to do it from LXD (snapcraft cleanbuild).


#8

Does movies.sh have executable permission assigned?

Try running in your project directory:

chmod +x ./movies.sh

Then rebuild your snap to see if that fixes it.

To be sure it gets executable permission inside the snap without forcing it in your project tree, you can add an override-pull block to the myparts part:

parts:
  myparts:
    source: .
    plugin: dump
    build-packages: […]
    override-pull: |
      snapcraftctl pull
      chmod +x ./movies.sh
    override-build: |
      gem install csv -I $SNAPCRAFT_PART_INSTALL
      snapcraftctl build
    stage-packages: […]

It looks like you’re also missing the snapcraftctl build line which I’ve added in my snippet above. You could try adding just that line first to see if that fixes it, and if it still complains add the override-pull and try a second time.