User Writable Config Files

I’m working on snapping up some rails apps, and am having difficulty linking in config files.

I have a config file (application.yml) that (is maintained with empty string values with the application code) that needs to live in the application config dir, but also needs to be modified with custom values post snap install.

My idea at an approach in accomplishing this was to have the install scriptlet move the application.yml to somewhere a user could modify it, and symlink to it from $SNAP/prm-app/config/application.yaml.

This way the application code could remain inside of the versioned $SNAP dir, and the config file could live outside of it, available for the user to modify, but still available to be consumed by the application.

The issue(s) I’ve been hitting seem to be such that I don’t have access to any of the snap env vars (other than $SNAP and $SNAPCRAFT_PARTS_INSTALL) from the install scriptlet. This is blocking me from moving and linking the application.yml where I’m trying to put it (either in $SNAP_COMMON or $SNAP_USER_COMMON).

Heres a paste to my snapcraft.yaml http://paste.ubuntu.com/25012754/. Lines 43-47 are where I’m trying to haggle the moving and linking.

Line 37 (setting RAILS_ENV) is another place I’m slightly lost as to what/where/how to make configurable on a per deploy basis.

Any insight here would be greatly appreciated.

Thanks

Assuming your “wrappers” are shell scripts, simply put your env vars into your wrappers :wink: (or in a file you source from every wrapper so you can maintain it in a central place)

Regarding the config i’d also have the wrappers check for it and put it in place if it does not exist yet. That way you have all writable dirs available in properly assigned variables:

$ sudo snap install hello-world
$ hello-world.env |grep ^SNAP
SNAP_USER_COMMON=/home/ogra/snap/hello-world/common
SNAP_LIBRARY_PATH=/var/lib/snapd/lib/gl:
SNAP_COMMON=/var/snap/hello-world/common
SNAP_USER_DATA=/home/ogra/snap/hello-world/27
SNAP_DATA=/var/snap/hello-world/27
SNAP_REVISION=27
SNAP_NAME=hello-world
SNAP_ARCH=amd64
SNAP_VERSION=6.3
SNAP=/snap/hello-world/27

Note that you can not write anywhere outside of these defined areas … I see you are trying to create a dir in /srv/prm/config … that wont be allowed. A snap can only write to its own writable areas (SNAP_COMMON, SNAP_USER_DATA and SNAP_DATA). Accessing any filesystem place in the system is only allowed through interfaces (and there is no interface that would allow you write access to /srv)

@ogra thanks for the response.

“Regarding the config i’d also have the wrappers check for it and put it in place if it does not exist yet. That way you have all writable dirs available in properly assigned variables” - I guess my confusion lies within this part.

What I feel like I need to do in that case, is swap out /srv/prm/config with $SNAP_COMMON, but I’m a bit confused about how you get things into $SNAP_COMMON if it can’t be accessed from the scriptlet?

Can you shed some light on this possibly?

Thanks

Well, i wasn’t talking about the scriptlet but about your wrapper script …

apps:
  rake:
    command: wrappers/rake.sh

and having rake.sh be something like:

#! /bin/sh

[ -e "$SNAP_COMMON/config.xml" ] || cp $SNAP/whereever/config.xml $SNAP_COMMON/

exec wrappers/rake "$@"

At runtime all the variables i showed in the former posts will point to proper dirs… unlike at build time (which is when the scriptlet is used)

Currently, I use a gem called ‘figaro’ to get vars into my app env. Figaro looks for config/application.yml, and puts the contents of application.yml into the env. I was thinking I wanted to symlink from $SNAP/prm-app/config/application.yml to the application.yml in $SNAP_COMMON (such that the application.yml could be configured by user). SO I was trying to think of a way to get a template application.yml to preexist in $SNAP_COMMON such that the link could exist and the app could start prior to the user going in and configuring it.

I’m thinking I can just drop figaro all together, and have the wrapper for nginx-passenger source the vars into the env from something in $SNAP_COMMON before it starts nginx-passenger. Since nginx-passenger drives the app, it will by default pass the vars through to the rails application.

This sounds far less convoluted. I guess I just need to start a part for nginx-passenger then…