diff --git a/.gitignore b/.gitignore index c7d23a9df8..33974acbe2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ .DS_Store .php_cs.cache debug/ -app/sdks \ No newline at end of file +app/sdks +dev/yasd_init.php diff --git a/CHANGES.md b/CHANGES.md index 5743bd42e5..94b56bc7a0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,11 @@ +# Version 0.9.1 + +## Bugs + +- Fixed PDO Connection timeout (#1385) +- Removed unnecessary `app` resource and replace with `utopia` (#1384) +- Fixed missing quote in Functions Worker logs (#1375) + # Version 0.9.0 ## Features diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e1d2cd3ec4..552ff05612 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -282,6 +282,30 @@ docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 The Runtimes for all supported cloud functions (multicore builds) can be found at the [appwrite/php-runtimes](https://github.com/appwrite/php-runtimes) repository. +## Debug + +Appwrite uses [yasd](https://github.com/swoole/yasd) debugger, which can be made available during build of Appwrite. You can connect to the debugger using VS Code [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension or if you are in PHP Storm you don't need any plugin. Below are the settings required for remote debugger connection. + +First, you need to create an init file. Duplicate **dev/yasd_init.php.stub** file and name it **dev/yasd_init.php** and there change the IP address to your development machine's IP. Without the proper IP address debugger wont connect. And you also need to set **DEBUG** build arg in **appwrite** service in **docker-compose.yml** file. + +### VS Code Launch Configuration + +```json +{ + "name": "Listen for Xdebug", + "type": "php", + "request": "launch", + "port": 9005, + "pathMappings": { + "/usr/src/code": "${workspaceRoot}" + }, +} +``` + +### PHPStorm Setup + +In settings, go to **Languages & Frameworks** > **PHP** > **Debug**, there under **Xdebug** set the debug port to **9005** and enable **can accept external connections** checkbox. + ## Tests To run all tests manually, use the Appwrite Docker CLI from your terminal: diff --git a/Dockerfile b/Dockerfile index b450b6a6d9..d15dbf508e 100755 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,9 @@ RUN composer update --ignore-platform-reqs --optimize-autoloader \ FROM php:8.0-cli-alpine as step1 +ARG DEBUG=false +ENV DEBUG=$DEBUG + ENV PHP_REDIS_VERSION=5.3.4 \ PHP_SWOOLE_VERSION=v4.6.7 \ PHP_IMAGICK_VERSION=3.5.0 \ @@ -75,11 +78,25 @@ RUN \ make && make install && \ cd ../.. +## Swoole Debugger setup +RUN if [ "$DEBUG" == "true" ]; then \ + cd /tmp && \ + apk add boost-dev && \ + git clone --depth 1 https://github.com/swoole/yasd && \ + cd yasd && \ + phpize && \ + ./configure && \ + make && make install && \ + cd ..;\ + fi + FROM php:8.0-cli-alpine as final LABEL maintainer="team@appwrite.io" ARG VERSION=dev +ARG DEBUG=false +ENV DEBUG=$DEBUG ENV _APP_SERVER=swoole \ _APP_ENV=production \ @@ -160,10 +177,15 @@ RUN \ && apk del .deps \ && rm -rf /var/cache/apk/* +RUN \ + if [ "$DEBUG" == "true" ]; then \ + apk add boost boost-dev; \ + fi + WORKDIR /usr/src/code COPY --from=step0 /usr/local/src/vendor /usr/src/code/vendor -COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/ +COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/swoole.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yasd.so* /usr/local/lib/php/extensions/no-debug-non-zts-20200930/ COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/redis.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/ COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/imagick.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/ COPY --from=step1 /usr/local/lib/php/extensions/no-debug-non-zts-20200930/yaml.so /usr/local/lib/php/extensions/no-debug-non-zts-20200930/ @@ -218,7 +240,9 @@ RUN echo extension=redis.so >> /usr/local/etc/php/conf.d/redis.ini RUN echo extension=imagick.so >> /usr/local/etc/php/conf.d/imagick.ini RUN echo extension=yaml.so >> /usr/local/etc/php/conf.d/yaml.ini RUN echo extension=maxminddb.so >> /usr/local/etc/php/conf.d/maxminddb.ini +RUN if [ "$DEBUG" == "true" ]; then printf "zend_extension=yasd \nyasd.debug_mode=remote \nyasd.init_file=/usr/local/dev/yasd_init.php \nyasd.remote_port=9005 \nyasd.log_level=-1" >> /usr/local/etc/php/conf.d/yasd.ini; fi +RUN if [ "$DEBUG" == "true" ]; then echo "opcache.enable=0" >> /usr/local/etc/php/conf.d/appwrite.ini; fi RUN echo "opcache.preload_user=www-data" >> /usr/local/etc/php/conf.d/appwrite.ini RUN echo "opcache.preload=/usr/src/code/app/preload.php" >> /usr/local/etc/php/conf.d/appwrite.ini RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/appwrite.ini diff --git a/README.md b/README.md index f584c93a97..895da87d6c 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ - appwrite/appwrite:0.9.0 + appwrite/appwrite:0.9.1 ``` ### Windows @@ -68,7 +68,7 @@ docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ --entrypoint="install" ^ - appwrite/appwrite:0.9.0 + appwrite/appwrite:0.9.1 ``` #### PowerShell @@ -78,7 +78,7 @@ docker run -it --rm , --volume /var/run/docker.sock:/var/run/docker.sock , --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw , --entrypoint="install" , - appwrite/appwrite:0.9.0 + appwrite/appwrite:0.9.1 ``` Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-linux native hosts, the server might take a few minutes to start after installation completes. diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php index 850f42af58..37ab46166d 100644 --- a/app/controllers/api/account.php +++ b/app/controllers/api/account.php @@ -918,16 +918,16 @@ App::get('/v1/account/logs') ->inject('user') ->inject('locale') ->inject('geodb') - ->inject('app') - ->action(function ($response, $project, $user, $locale, $geodb, $app) { + ->inject('utopia') + ->action(function ($response, $project, $user, $locale, $geodb, $utopia) { /** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Database\Document $project */ /** @var Appwrite\Database\Document $user */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - /** @var Utopia\App $app */ + /** @var Utopia\App $utopia */ - $adapter = new AuditAdapter($app->getResource('db')); + $adapter = new AuditAdapter($utopia->getResource('db')); $adapter->setNamespace('app_'.$project->getId()); $audit = new Audit($adapter); diff --git a/app/controllers/api/health.php b/app/controllers/api/health.php index a161b2bdea..cbccb8f59c 100644 --- a/app/controllers/api/health.php +++ b/app/controllers/api/health.php @@ -42,11 +42,11 @@ App::get('/v1/health/db') ->label('sdk.method', 'getDB') ->label('sdk.description', '/docs/references/health/get-db.md') ->inject('response') - ->inject('app') - ->action(function ($response, $app) { + ->inject('utopia') + ->action(function ($response, $utopia) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\App $app */ - $app->getResource('db'); + /** @var Utopia\App $utopia */ + $utopia->getResource('db'); $response->json(['status' => 'OK']); }); @@ -60,11 +60,11 @@ App::get('/v1/health/cache') ->label('sdk.method', 'getCache') ->label('sdk.description', '/docs/references/health/get-cache.md') ->inject('response') - ->inject('app') - ->action(function ($response, $app) { + ->inject('utopia') + ->action(function ($response, $utopia) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\App $register */ - $app->getResource('cache'); + /** @var Utopia\App $utopia */ + $utopia->getResource('cache'); $response->json(['status' => 'OK']); }); diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index a11c65edc5..e73a0a2f74 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -236,14 +236,14 @@ App::get('/v1/users/:userId/logs') ->inject('projectDB') ->inject('locale') ->inject('geodb') - ->inject('app') - ->action(function ($userId, $response, $project, $projectDB, $locale, $geodb, $app) { + ->inject('utopia') + ->action(function ($userId, $response, $project, $projectDB, $locale, $geodb, $utopia) { /** @var Appwrite\Utopia\Response $response */ /** @var Appwrite\Database\Document $project */ /** @var Appwrite\Database\Database $projectDB */ /** @var Utopia\Locale\Locale $locale */ /** @var MaxMind\Db\Reader $geodb */ - /** @var Utopia\App $app */ + /** @var Utopia\App $utopia */ $user = $projectDB->getDocument($userId); @@ -251,7 +251,7 @@ App::get('/v1/users/:userId/logs') throw new Exception('User not found', 404); } - $adapter = new AuditAdapter($app->getResource('db')); + $adapter = new AuditAdapter($utopia->getResource('db')); $adapter->setNamespace('app_'.$project->getId()); $audit = new Audit($adapter); diff --git a/app/controllers/general.php b/app/controllers/general.php index cd95b74a0c..708e249853 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -304,6 +304,10 @@ App::error(function ($error, $utopia, $request, $response, $layout, $project) { /** @var Utopia\View $layout */ /** @var Appwrite\Database\Document $project */ + if ($error instanceof PDOException) { + throw $error; + } + $route = $utopia->match($request); $template = ($route) ? $route->getLabel('error', null) : null; diff --git a/app/http.php b/app/http.php index 6b216da802..9a3a5459da 100644 --- a/app/http.php +++ b/app/http.php @@ -87,10 +87,6 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo App::setResource('cache', function () use (&$redis) { return $redis; }); - - App::setResource('app', function() use (&$app) { - return $app; - }); try { Authorization::cleanRoles(); @@ -103,6 +99,13 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo Console::error('[Error] File: '.$th->getFile()); Console::error('[Error] Line: '.$th->getLine()); + /** + * Reset Database connection if PDOException was thrown. + */ + if ($th instanceof PDOException) { + $db = null; + } + if(App::isDevelopment()) { $swooleResponse->end('error: '.$th->getMessage()); } diff --git a/app/init.php b/app/init.php index 302ce0f650..6461f50acb 100644 --- a/app/init.php +++ b/app/init.php @@ -48,7 +48,7 @@ const APP_MODE_DEFAULT = 'default'; const APP_MODE_ADMIN = 'admin'; const APP_PAGING_LIMIT = 12; const APP_CACHE_BUSTER = 149; -const APP_VERSION_STABLE = '0.9.0'; +const APP_VERSION_STABLE = '0.9.1'; const APP_STORAGE_UPLOADS = '/storage/uploads'; const APP_STORAGE_FUNCTIONS = '/storage/functions'; const APP_STORAGE_CACHE = '/storage/cache'; @@ -164,12 +164,11 @@ $register->set('dbPool', function () { // Register DB connection $pool = new PDOPool((new PDOConfig()) ->withHost($dbHost) ->withPort($dbPort) - // ->withUnixSocket('/tmp/mysql.sock') ->withDbName($dbScheme) ->withCharset('utf8mb4') ->withUsername($dbUser) ->withPassword($dbPass) - ); + , 16); return $pool; }); @@ -189,7 +188,7 @@ $register->set('redisPool', function () { ->withPort($redisPort) ->withAuth($redisAuth) ->withDbIndex(0) - ); + , 16); return $pool; }); @@ -468,7 +467,7 @@ App::setResource('user', function($mode, $project, $console, $request, $response $user = $projectDB->getDocument($jwtUserId); } - if (empty($user->search('$id', $jwtSessionId, $user->getAttribute('tokens')))) { // Match JWT to active token + if (empty($user->search('$id', $jwtSessionId, $user->getAttribute('sessions')))) { // Match JWT to active token $user = new Document(['$id' => '', '$collection' => Database::SYSTEM_COLLECTION_USERS]); } } diff --git a/app/tasks/install.php b/app/tasks/install.php index 755e0b7e2c..483f5c5e04 100644 --- a/app/tasks/install.php +++ b/app/tasks/install.php @@ -129,7 +129,7 @@ $cli $httpsPort = Console::confirm('Choose your server HTTPS port: (default: '.$defaultHTTPSPort.')'); $httpsPort = ($httpsPort) ? $httpsPort : $defaultHTTPSPort; } - + $input = []; foreach($vars as $key => $var) { @@ -196,7 +196,7 @@ $cli foreach ($input as $key => $value) { if($value) { - $env .= $key.'='.$value.' '; + $env .= $key.'='.\escapeshellarg($value).' '; } } diff --git a/app/views/install/compose.phtml b/app/views/install/compose.phtml index 1acc350664..c110fcd4eb 100644 --- a/app/views/install/compose.phtml +++ b/app/views/install/compose.phtml @@ -342,7 +342,7 @@ services: - MYSQL_DATABASE=${_APP_DB_SCHEMA} - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - command: 'mysqld --innodb-flush-method=fsync' + command: 'mysqld --innodb-flush-method=fsync --wait_timeout=86400' redis: image: redis:6.0-alpine3.12 diff --git a/composer.lock b/composer.lock index 4bb236099e..fba3b66cee 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7983e9fe8946a99fbf818b79ff202486", + "content-hash": "e24aacead283e33130051470bb4312e6", "packages": [ { "name": "adhocore/jwt", @@ -2403,16 +2403,16 @@ }, { "name": "appwrite/sdk-generator", - "version": "dev-feat-kotlin-java-docs", + "version": "0.12.0", "source": { "type": "git", "url": "https://github.com/appwrite/sdk-generator.git", - "reference": "966d464728b41a8c449e99d7df4bd4ddca591a25" + "reference": "ca8e34f091b3a66f94a8972cb94b0b8e1161dada" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/966d464728b41a8c449e99d7df4bd4ddca591a25", - "reference": "966d464728b41a8c449e99d7df4bd4ddca591a25", + "url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ca8e34f091b3a66f94a8972cb94b0b8e1161dada", + "reference": "ca8e34f091b3a66f94a8972cb94b0b8e1161dada", "shasum": "" }, "require": { @@ -2446,9 +2446,9 @@ "description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms", "support": { "issues": "https://github.com/appwrite/sdk-generator/issues", - "source": "https://github.com/appwrite/sdk-generator/tree/feat-kotlin-java-docs" + "source": "https://github.com/appwrite/sdk-generator/tree/0.12.0" }, - "time": "2021-07-06T09:26:45+00:00" + "time": "2021-07-06T16:20:51+00:00" }, { "name": "composer/package-versions-deprecated", @@ -6066,9 +6066,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "appwrite/sdk-generator": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -6090,5 +6088,5 @@ "platform-overrides": { "php": "8.0" }, - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.0.0" } diff --git a/dev/yasd_init.php.stub b/dev/yasd_init.php.stub new file mode 100644 index 0000000000..a7d977fbf7 --- /dev/null +++ b/dev/yasd_init.php.stub @@ -0,0 +1,4 @@ + 'V06', '0.8.0' => 'V07', '0.9.0' => 'V08', + '0.9.1' => 'V08', ]; /**