1

I am trying to mount a GCS bucket on AppEngine Flexible Environment app using gcsfuse.

My Dockerfiles includes the following:

# gscfuse setup
RUN echo "deb http://packages.cloud.google.com/apt cloud-sdk-jessie main" | tee /etc/apt/sources.list.d/google-cloud.sdk.list
RUN echo "deb http://packages.cloud.google.com/apt gcsfuse-jessie main" | tee /etc/apt/sources.list.d/gcsfuse.list
RUN wget -qO- https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
RUN apt-get update && apt-get install -y --no-install-recommends google-cloud-sdk gcsfuse strace
RUN gcsfuse --implicit-dirs my_bucket my_dir

I took most of this from here. It's pretty much just the standard way to install gcsfuse, plus --no-install-recommends.

If I start an app this way, it does not mount the drive. This was not too surprising to me, since it didn't seem like a supported feature of the flexible environment.

Here is the confusing part. If I run gcloud app instances ssh "<instance>", then run container_exec gaeapp /bin/bash, then gcsfuse my_bucket my_dir works fine.

However, if I run gcloud app instances ssh "<instance>" --container gaeapp, then gcsfuse my_bucket my_dir fails with this error:

fusermount: failed to open /dev/fuse: Operation not permitted

This is the same error I get if I run gcsfuse as a subprocess in my main.py.

Based on this unresolved thread, I ran strace -f and saw the exact same problem as that user did, an EPERM issue.

[pid    59] open("/dev/fuse", O_RDWR)   = -1 EPERM (Operation not permitted)

Whichever way I log into the container (or if I run a subprocess from main.py), I am user root. If I run export then I do see different vars, so there is some difference in what's being run, but everything else looks the same to me.

Other suggestions I've seen include using the gcsfuse flags -o allow_other and -o allow_root. These did not work.

There may be a clue in the fact that if I try to run umount on a login that cannot run gcsfuse, it says "must be superuser to unmount", even though I am root.

It seems like there is probably some security setting that I do not understand. However, since I could in theory get main.py to trigger an external program to log in and run gcsfuse for me, it seems like there should be a way to get it to work without having to do that.

hgbrian
  • 23
  • 1
  • 3

1 Answers1

0

RUN commands are about creating a new layer for your dockerfile, so you're actually running that command during the image creation, which the Flex build system doesn't like.

I'm not sure why shelling out in the application didn't work, you could try 'sudo'ing it in the python subprocess, or possibly push it out of the application code by adding 'gcsfuse setup &&' to the ENTRYPOINT in the dockerfile.

  • Thanks Jon. I tried these ideas. The entrypoint did not work for me (running the gcsfuse command && gunicorn). Trying to call sudo from python subprocess didn't work because sudo was not found (the user is root anyway). The major mystery to me is the difference between sshing to the instance, then running container_exec (gcsfuse works) vs sshing with --container gaeapp (gcsfuse fails). – hgbrian Oct 12 '17 at 17:59