Support setting working directory for snaps

Hi,

I am currently refactoring a large wrapper script which starts up multiple services into individual daemons inside the snapcraft.yaml of the snap, and I find that for a number of these services I still need wrapper scripts because these services need to all be started from a different working directory, so I now have a bunch of scripts like this:

#!/bin/bash -e
cd $SNAP_DATA/some-dir
exec $SNAP/bin/service-thing "${@:1}"

Because we have an environment keyword for setting environment variables, I’d like to propose an additional key inside an app’s yaml spec for the purpose of setting the working directory of the process. Something like this:

  service:
    command: bin/service
    daemon: simple
    environment:
      FOO: BAR
    working-directory: ${SNAP_DATA}/some-dir
    plugs: [network, network-bind]

This could either be implemented in snapd for the snap.yaml as well, or it could just be a pure snapcraft.yaml thing that just affects the generated wrapper. I personally would like to see the wrappers go away as much as possible, so I’d prefer the snap.yaml support as well, but if folks are opposed to it there maybe just start with support inside snapcraft.yaml.

Thoughts?

5 Likes

@sergiusens thoughts on this proposal?

Even though I am +1 on this, it is a thing that the runtime folks should decide on and after early implementation can be tried by use of passthrough in snapcraft.

@pedronis when you get a chance can you review this proposal?

I think we discussed something like this already quickly and the agreement is that it would be ok in snapd itself.

  • we probably want to implement this initially only for services
  • working-directory seems a fine option name
  • we need to think how we can sanity check the directory value, whether we want restrictions on it, maybe @jdstrand has input on that

I propose to start that if the command is a service (specifies daemon), then the normalized path must start with $SNAP_DATA/, $SNAP_COMMON/ or $SNAP/.

If you were to extend this to non-services (daemon not specified), you could expand the list to include $SNAP_USER_COMMON/ and $SNAP_USER_DATA/

This should provide lots of flexibility and works with default policy. People can continue to use wrappers for other cases, and we can evaluate incorporating those cases as we go.

What about for snap apps that plug the home interface? If they plug the home interface it’s reasonable to want to have the working directory be set as $HOME - though I’m not sure whether this should be $HOME/snap/$SNAP_NAME/$SNAP_REVISION or the user’s actual $HOME.

Also note that yes, for a first iteration all of the use cases I’ve seen/wanted would still be solved with the restrictions you mention.

It is conceivable that we could allow $HOME/something, but for this to be a good experience, we would need to ensure the home interface is connected and that the directory exists. Plus, even if it was auto-connected, the user could disconnect it. We know that the various $SNAP* dirs will exist and the be accessible, but deciding what to do with arbitrary directories would add complexity and likely degrade the user experience. Before we go down that road, I’d like to see how the first phase goes and then understand specific use cases.

1 Like