-
Notifications
You must be signed in to change notification settings - Fork 11
Description
Hi,
we want to use the S3 plugin to store the attachments in a bucket on our MinIO instance. Currently our MinIO is setted up as a single-node. In MinIO I have created a fresh bucket and created an access key with secret for this bucket. In our test environment the access key have all permissions for MinIO. Sadly we receive an error in the log on GuzzleHttp level.
After this, we have tryed to use the public MinIO play instance (https://play.min.io), same error.
I have created a PR for a fix for that: #16
Actual behaviour
Attachment upload shows that it was successful but after we close the dialog the attachment list doesn't contain the uploaded file.
Expected behaviour
Attachment upload successfully stored in S3 bucket or a proper error message is displayed that the upload was not successful. In debug.log we expect more details.
Steps to reproduce
1.) In config.php set the required parameters and restart your container or kanboard instance:
define('AWS_KEY', 'Q3AM3UQ867SPQQA43P2F');
define('AWS_SECRET', 'zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG');
define('AWS_S3_BUCKET', 'kanboard');
define('AWS_S3_PREFIX', 'kanboard-objects');
define('AWS_S3_REGION', 'us-east-1');
define('AWS_S3_OPTIONS', json_encode(['version' => 'latest', 'endpoint' => 'https://play.min.io', 'use_path_style_endpoint' => true]));
Note, this is the public MinIO play instance, the credentials are available for public usage!
2.) Try to upload an attachment to an existing task
3.) Have a look at stderr or stdout or debug.log (depends on your configuration)
[Mon Aug 7 23:24:29 2023] PHP Fatal error: Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php:67
Stack trace:
#0 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php(67): count(NULL)
#1 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php(107): GuzzleHttp\Handler\CurlFactory->release(Object(GuzzleHttp\Handler\EasyHandle))
#2 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(179): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(108): GuzzleHttp\Handler\CurlMultiHandler->processMessages()
#4 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(123): GuzzleHttp\Handler\CurlMultiHandler->tick()
#5 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#6 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#7 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(266): GuzzleHttp\Promise\Promise->waitIfPending()
#8 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#9 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#10 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#11 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#12 D.\dev\kanboard\src\plugins\S3\vendor\Aws\AwsClientTrait.php(59): GuzzleHttp\Promise\Promise->wait()
#13 D.\dev\kanboard\src\plugins\S3\vendor\Aws\AwsClientTrait.php(78): Aws\AwsClient->execute(Object(Aws\Command))
#14 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(179): Aws\AwsClient->__call('putObject', Array)
#15 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(910): Aws\S3\StreamWrapper->Aws\S3\{closure}()
#16 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(180): Aws\S3\StreamWrapper->boolCall(Object(Closure))
#17 [internal function]: Aws\S3\StreamWrapper->stream_flush()
#18 D.\dev\kanboard\src\plugins\S3\S3Storage.php(121): file_put_contents('s3://kanboard/k...', 'this is a test')
#19 D.\dev\kanboard\src\plugins\S3\S3Storage.php(139): Kanboard\Plugin\S3\S3Storage->moveFile('D:\\dev\\php\\tmp\\...', 'tasks\\1\\0977047...')
#20 D.\dev\kanboard\src\app\Model\FileModel.php(315): Kanboard\Plugin\S3\S3Storage->moveUploadedFile('D:\\dev\\php\\tmp\\...', 'tasks\\1\\0977047...')
#21 D.\dev\kanboard\src\app\Model\FileModel.php(288): Kanboard\Model\FileModel->uploadFile(1, Array)
#22 D.\dev\kanboard\src\app\Controller\TaskFileController.php(56): Kanboard\Model\FileModel->uploadFiles(1, Array)
#23 D.\dev\kanboard\src\app\Core\Controller\Runner.php(77): Kanboard\Controller\TaskFileController->save()
#24 D.\dev\kanboard\src\app\Core\Controller\Runner.php(31): Kanboard\Core\Controller\Runner->executeController()
#25 D.\dev\kanboard\src\index.php(9): Kanboard\Core\Controller\Runner->execute()
#26 {main}
thrown in D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php on line 67
[Mon Aug 7 23:24:29 2023] 127.0.0.1:65356 [200]: POST /?controller=TaskFileController&action=save&task_id=1 - Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php:67
Stack trace:
#0 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php(67): count(NULL)
#1 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php(107): GuzzleHttp\Handler\CurlFactory->release(Object(GuzzleHttp\Handler\EasyHandle))
#2 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(179): GuzzleHttp\Handler\CurlFactory::finish(Object(GuzzleHttp\Handler\CurlMultiHandler), Object(GuzzleHttp\Handler\EasyHandle), Object(GuzzleHttp\Handler\CurlFactory))
#3 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(108): GuzzleHttp\Handler\CurlMultiHandler->processMessages()
#4 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlMultiHandler.php(123): GuzzleHttp\Handler\CurlMultiHandler->tick()
#5 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(246): GuzzleHttp\Handler\CurlMultiHandler->execute(true)
#6 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(223): GuzzleHttp\Promise\Promise->invokeWaitFn()
#7 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(266): GuzzleHttp\Promise\Promise->waitIfPending()
#8 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#9 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(269): GuzzleHttp\Promise\Promise->waitIfPending()
#10 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(225): GuzzleHttp\Promise\Promise->invokeWaitList()
#11 D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Promise\Promise.php(62): GuzzleHttp\Promise\Promise->waitIfPending()
#12 D.\dev\kanboard\src\plugins\S3\vendor\Aws\AwsClientTrait.php(59): GuzzleHttp\Promise\Promise->wait()
#13 D.\dev\kanboard\src\plugins\S3\vendor\Aws\AwsClientTrait.php(78): Aws\AwsClient->execute(Object(Aws\Command))
#14 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(179): Aws\AwsClient->__call('putObject', Array)
#15 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(910): Aws\S3\StreamWrapper->Aws\S3\{closure}()
#16 D.\dev\kanboard\src\plugins\S3\vendor\Aws\S3\StreamWrapper.php(180): Aws\S3\StreamWrapper->boolCall(Object(Closure))
#17 [internal function]: Aws\S3\StreamWrapper->stream_flush()
#18 D.\dev\kanboard\src\plugins\S3\S3Storage.php(121): file_put_contents('s3://kanboard/k...', 'this is a test')
#19 D.\dev\kanboard\src\plugins\S3\S3Storage.php(139): Kanboard\Plugin\S3\S3Storage->moveFile('D:\\dev\\php\\tmp\\...', 'tasks\\1\\0977047...')
#20 D.\dev\kanboard\src\app\Model\FileModel.php(315): Kanboard\Plugin\S3\S3Storage->moveUploadedFile('D:\\dev\\php\\tmp\\...', 'tasks\\1\\0977047...')
#21 D.\dev\kanboard\src\app\Model\FileModel.php(288): Kanboard\Model\FileModel->uploadFile(1, Array)
#22 D.\dev\kanboard\src\app\Controller\TaskFileController.php(56): Kanboard\Model\FileModel->uploadFiles(1, Array)
#23 D.\dev\kanboard\src\app\Core\Controller\Runner.php(77): Kanboard\Controller\TaskFileController->save()
#24 D.\dev\kanboard\src\app\Core\Controller\Runner.php(31): Kanboard\Core\Controller\Runner->executeController()
#25 D.\dev\kanboard\src\index.php(9): Kanboard\Core\Controller\Runner->execute()
#26 {main}
thrown in D.\dev\kanboard\src\plugins\S3\vendor\GuzzleHttp\Handler\CurlFactory.php on line 67
Configuration
- Plugin version: 1.0.5
- Kanboard version: 1.2.32
- Database type and version: Sqlite | MySQL 8
- PHP version: 8.1.17 | 8.2.3
- OS: Windows | Linux
- Browser: Chrome | Edge | Firefox