0

Hi I have created a script that is supposed to make a set of image files public readable in a google storage bucket. Later another script will make them private again.

The scripts is running on a GCE (Google compute engine). It starts running fine, and sets files public, but before it has finished with all files it encounters the following fatal exception

Uncaught exception 'DomainException' with message 'Could not load the default credentials. in (...)/vendor/google/auth/src/ApplicationDefaultCredentials.php:148
Stack trace: 
    #0 (...)/vendor/google/apiclient/src/Google/Client.php(1053): Google\Auth\ApplicationDefaultCredentials::getCredentials('https://www.goo...') 
    #1 (...)/vendor/google/apiclient/src/Google/Client.php(354): Google_Client->createApplicationDefaultCredentials() 
    #2 (...)/vendor/google/apiclient/src/Google/Client.php(777): Google_Client->authorize() 
    #3 (...)/vendor/google/apiclient/src/Google/Service/Resource.php(232): Google_Client->execute(Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') 
    #4 (...)/vendor/google/auth/src/ApplicationDefaultCredentials.php on line 148

The code I'm using is the following.

require "../vendor/autoload.php";
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Storage::DEVSTORAGE_READ_WRITE);

$storage = new Google_Service_Storage($client);

$acl = new Google_Service_Storage_ObjectAccessControl();
$acl->setEntity('allUsers');
$acl->setRole('READER');

foreach($objects as $object){
    $files = $storage->objects->listObjects($GLOBALS["bucket"],array("prefix"=>$object->name()));
    $thumbs = $storage->objects->listObjects($GLOBALS["bucket"],array("prefix"=>"thumb/".$object->thumb()));
    $files = array_merge($files["items"],$thumbs["items"]);
    foreach($files as $file){
        if(strpos($file["name"],".pdf")===false)
        $storage->objectAccessControls->insert($GLOBALS["bucket"], $file["name"], $acl);
    }
}

Anyone with any suggestions why the default credentials sometime can't be found?

Update

I have changed my code to make use of the "gsutil acl ch" command through the use of php's "exec" command. This works without any problems, and quite a bit faster because i can run the gsutil as mulitprocess with the -m parameter.

But the question of why the other script fails to retrieve the default credentials sometimes still stands. I tried to wrap the function in a try/catch block forcing it to retry a few times when it encountered the exception. On these retries the default credentials could be found again, and the script continued droning on setting the ACL on files till it failed again.

  • Have you setted the GOOGLE_APPLICATION_CREDENTIALS environment variable as described here: github.com/google/… ? – marcogramy Oct 2 '16 at 15:22
  • @marcogramy That shouldn't be necessary when running on a Google Compute Engine as specified here under point 4. And my problem is still that it works most of the time (95%+) but sometime fails to locate the credentials. – Zeohye Oct 4 '16 at 7:35
  • @Zeohye Did you have the chance to check the API quota limit? I would suggest adding a small pause while running the script and try again, as you pointed out that retrying resolves the issue. – George Dec 8 '16 at 17:14
  • @George It has been some time since the question, and as updated I moved to another solution. But as I remember, I tried adding a small delay without any luck. I once since then experienced the same problem but in a function that only made one of 2 calls to the API and the problem was gone after a page reload. It Might still be an quota limit if theres a max calls/min. Would just seem odd since it's a call made on the instance of the VM, not a call to any google service. – Zeohye Dec 12 '16 at 7:41
  • 1
    It seems that in this case the issue got actually solved by setting the environment variable. – Carlos Feb 7 '17 at 17:48
1

It seems like the never versions of the API doesn't have the same problems.

The newer version is slightly different than the old one. Instead of making a Google_Client object a I have been using their ServiceBuilder. The code now looks like this.

    $builder = new ServiceBuilder([
            'projectId' => "[projectID]",
            'keyFilePath' => "[keyFilePath]",
    ]);
    $bucket = $builder->storage()->bucket("[bucketName]");
    $objects = $this->bucket->objects(["prefix"=>"[PathPrefix]"]);
    foreach($objects as $object)
        $object->acl()->add("allUsers","READER");

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.