GaeSupportL5 icon indicating copy to clipboard operation
GaeSupportL5 copied to clipboard

Support multiple buckets

Open atrauzzi opened this issue 10 years ago • 19 comments

If I'm correct in reading the current code, it looks like the first bucket configured in php.ini is the one that this package uses.

Would it be worthwhile to allow the bucket used to be configured at a driver/L5 filesystem level?

atrauzzi avatar Aug 28 '15 14:08 atrauzzi

As of now the first enabled GSC bucket is used for storage_path(). By default GAE Filesystem wrapper uses storage_path().'/app' as its root. storage_path() is determined according to the environment the app is running on, i.e. GAE or non-GAE, and will work properly in local and production environments. If a specific filesystem wrapper is configured with some GCS bucket path it will fail in local environment, although it will work in production.

shpasser avatar Aug 30 '15 11:08 shpasser

But I could convert disk root path from gs://{$bucket}/some_path to storage_path()."/{$bucket}/some_path" when running not on GAE.

shpasser avatar Aug 31 '15 05:08 shpasser

Any thoughts?

shpasser avatar Sep 04 '15 13:09 shpasser

I'm kind of torn between the simplicity of it all just being file paths, but the explicitness of using straight-up bucket names.

Something I did in my build setup (which is not optimal) is run my php.ini through sed. This has given me the ability to use a dns-named bucket for static hosting (as opposed to the default one GAE creates).

That prompted this: https://code.google.com/p/googleappengine/issues/detail?id=12297

Based on all this though, I'm inclined to think that we should have somewhere in our applications an environment variable that defines which bucket we want to use. Which then gets picked up by configurations of the gae filesystem driver. Whether it's #default# or a specific name.

Hopefully what I said makes sense or has some valuable takeaways ;)

atrauzzi avatar Sep 04 '15 13:09 atrauzzi

Does this help?

    /**
     * Override the storage path
     *
     * @return string Storage path URL
     */
    public function storagePath()
    {
        if ($this->runningOnGae)
        {
            if ( ! is_null($this->gaeBucketPath))
            {
                return $this->gaeBucketPath;
            }

            $buckets = ini_get('google_app_engine.allow_include_gs_buckets');

            // Get the defined bucket or the first bucket in the list.
            $bucket = env('GAE_GCS_BUCKET', current(explode(', ', $buckets)));

            if ($bucket)
            {
                $this->gaeBucketPath = "gs://{$bucket}/storage";

                if (env('GAE_SKIP_GCS_INIT'))
                {
                    return $this->gaeBucketPath;
                }

                if ( ! file_exists($this->gaeBucketPath))
                {
                    mkdir($this->gaeBucketPath);
                    mkdir($this->gaeBucketPath.'/app');
                    mkdir($this->gaeBucketPath.'/framework');
                    mkdir($this->gaeBucketPath.'/framework/views');
                }

                return $this->gaeBucketPath;
            }
        }

        return parent::storagePath();
    }

shpasser avatar Sep 04 '15 13:09 shpasser

$bucket = env('GAE_GCS_BUCKET', current(explode(', ', $buckets)));

Looks perfect.

atrauzzi avatar Sep 04 '15 15:09 atrauzzi

I will have to rearrange some of the documentation and add the environment variable to app.yaml (because it is needed before .env is loaded). Will keep you posted.

BTW, what did you mean by Is cachefs being phased out? (on gitter)

shpasser avatar Sep 04 '15 15:09 shpasser

Oh, sorry. I meant to follow up there, it's probably nothing. I just had seen some directories and files (services.json) being created in cloud storage that I thought were things going to cachefs. And it looks like they still are.

atrauzzi avatar Sep 06 '15 02:09 atrauzzi

Please notice that GAE_GCS_BUCKET variable will be added to app.yaml. Let me know if that's Ok.

Regarding services.json, I couldn't see any problems with my test application. The file is created in GCS when CACHE_SERVICES_FILE is false, but when CACHE_SERVICES_FILE is true it is created in cachefs(memcached). Please open an issue if there is a problem.

shpasser avatar Sep 06 '15 05:09 shpasser

Does GAE_GCS_BUCKET need to be in app.yaml to be available in time? It might be nicer to have it in .env if possible.

atrauzzi avatar Sep 07 '15 03:09 atrauzzi

When storagePath() first called .env is not yet loaded, besides the setting itself is GAE-only, why not put it in GAE related configuration file?

Anyway, I'm open to suggestions.

shpasser avatar Sep 07 '15 04:09 shpasser

Actually, I can return an instance of LazyString containing a callback to actual storage path initialization instead of the storage path string. Then I will be able to use environment variables stored in .env

class LazyString
{
    protected $getString;

    // Store a callback to storage path initialization function
    public function __construct(callable $getString)
    {
        $this->getString = $getString;
    }

    // Initialize the storage path and return its string value
    public function __toString()
    {
        return call_user_func($this->getString);
    }
}

It works, but is this bit of 'ease of use' worth the complexity of the solution?

shpasser avatar Sep 07 '15 18:09 shpasser

I guess the issue is that the bucket name is environment specific for me. I have staging and production buckets to ensure isolation. The only file I'd ideally like to touch during my build process is .env. Putting it in the .yaml would mean that all deployments have to use the same bucket. Unless I sed it. But that's honestly something I'm trying to get away from.

I have my request in with GAE to be able to select the default bucket for an app, which ought to cover 99% of the scenarios by setting it to #default#. But we're not there yet, and it is conceivable that someone could still have multiple buckets they want to use, even outside of any default.

atrauzzi avatar Sep 07 '15 20:09 atrauzzi

Just trying to understand, you would like to touch only .env file during the build process. On the other hand if #default# stuff will be implemented by GAE you'll probably have an option to set the default GSC bucket via php.ini. Then how does the last one solve the problem?

shpasser avatar Sep 08 '15 05:09 shpasser

php.ini is unavoidable because it's dictated by app engine. What would be ideal though is ignore the default and have laravel use exactly the bucket I want which will be set in .env.

#default# doesn't matter anymore at that point. It can be set to whatever it wants, my app at runtime will just choose the correct bucket to operate on based on my settings.

atrauzzi avatar Sep 08 '15 17:09 atrauzzi

In this case is it correct to say: GCS bucket == Laravel's storage path or would you like to use a GCS bucket as a disk(config/filesystems.php)?

shpasser avatar Sep 08 '15 18:09 shpasser

Currently, I'm using it for both. But it's possible that I might want to separate the two, or establish multiple buckets for my project.

atrauzzi avatar Sep 08 '15 19:09 atrauzzi

gitter?

shpasser avatar Sep 08 '15 19:09 shpasser

Sure thing.

atrauzzi avatar Sep 08 '15 19:09 atrauzzi