Compare commits

...
Author SHA1 Message Date
Matej BačoandGitHub a6b518a82c Merge branch 'feat-sites' into feat-zip-deployment 2025-02-13 09:38:56 +01:00
Matej Bačo caddb0a3d9 Update composer.lock 2025-02-12 17:13:38 +01:00
Matej Bačo 8ab09fff9a Remove todos 2025-02-11 15:14:08 +01:00
Matej Bačo 622ae009bd Implement ZIP site deployment 2025-02-08 21:22:36 +01:00
7 changed files with 118 additions and 22 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
FROM appwrite/base:0.9.5 AS final
FROM appwrite/base:0.9.7 AS final
LABEL maintainer="team@appwrite.io"
Generated
+6 -6
View File
@@ -5560,16 +5560,16 @@
},
{
"name": "myclabs/deep-copy",
"version": "1.12.1",
"version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845"
"reference": "024473a478be9df5fdaca2c793f2232fe788e414"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845",
"reference": "123267b2c49fbf30d78a7b2d333f6be754b94845",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414",
"reference": "024473a478be9df5fdaca2c793f2232fe788e414",
"shasum": ""
},
"require": {
@@ -5608,7 +5608,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.1"
"source": "https://github.com/myclabs/DeepCopy/tree/1.13.0"
},
"funding": [
{
@@ -5616,7 +5616,7 @@
"type": "tidelift"
}
],
"time": "2024-11-08T17:47:46+00:00"
"time": "2025-02-12T12:17:51+00:00"
},
{
"name": "nikic/php-parser",
@@ -261,8 +261,16 @@ class Builds extends Action
Console::execute('rm -rf ' . \escapeshellarg($tmpTemplateDirectory), '', $stdout, $stderr);
$directorySize = $deviceForFunctions->getFileSize($source);
$build = $dbForProject->updateDocument('builds', $build->getId(), $build->setAttribute('source', $source));
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment->setAttribute('path', $source)->setAttribute('size', $directorySize));
$build = $build->setAttribute('source', $source);
$deployment = $deployment
->setAttribute('path', $source)
->setAttribute('size', $directorySize)
->setAttribute('metadata', ['content_type' => 'application/gzip']);
$build = $dbForProject->updateDocument('builds', $build->getId(), $build);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
}
} elseif ($isNewBuild && $isVcsEnabled) {
// VCS and VCS+Temaplte
@@ -417,10 +425,16 @@ class Builds extends Action
Console::execute('rm -rf ' . \escapeshellarg($tmpPath), '', $stdout, $stderr);
$build = $dbForProject->updateDocument('builds', $build->getId(), $build->setAttribute('source', $source));
$directorySize = $deviceForFunctions->getFileSize($source);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment->setAttribute('path', $source)->setAttribute('size', $directorySize));
$build = $build->setAttribute('source', $source);
$deployment = $build
->setAttribute('path', $source)
->setAttribute('size', $directorySize)
->setAttribute('metadata', ['content_type' => 'application/gzip']);
$build = $dbForProject->updateDocument('builds', $build->getId(), $build);
$deployment = $dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
$this->runGitAction('processing', $github, $providerCommitHash, $owner, $repositoryName, $project, $resource, $deployment->getId(), $dbForProject, $dbForPlatform);
}
@@ -565,7 +579,22 @@ class Builds extends Action
Co::join([
Co\go(function () use ($executor, &$response, $project, $deployment, $source, $resource, $runtime, $vars, $command, $cpus, $memory, $timeout, &$err, $version) {
try {
$command = $version === 'v2' ? 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh' : 'tar -zxf /tmp/code.tar.gz -C /mnt/code && helpers/build.sh "' . \trim(\escapeshellarg($command), "\'") . '"';
$contentType = $deployment->getAttribute('metadata', [])['content_type'] ?? '';
$extractCommand = '';
switch ($contentType) {
case 'application/zip':
$extractCommand = 'unzip /tmp/code.tar.gz -d /mnt/code';
break;
case 'application/gzip':
$extractCommand = 'tar -zxf /tmp/code.tar.gz -C /mnt/code';
break;
default:
throw new \Exception('Unsupported deployment content type: ' . $contentType);
break;
}
$command = $version === 'v2' ? 'tar -zxf /tmp/code.tar.gz -C /usr/code && cd /usr/local/src/ && ./build.sh' : ($extractCommand . ' && helpers/build.sh "' . \trim(\escapeshellarg($command), "\'") . '"');
// TODO: Detect adapter if adapter is empty
$response = $executor->createRuntime(
@@ -119,7 +119,7 @@ class Create extends Action
throw new Exception(Exception::STORAGE_FILE_EMPTY, 'No file sent');
}
$fileExt = new FileExt([FileExt::TYPE_GZIP]);
$fileExt = new FileExt([FileExt::TYPE_GZIP, FileExt::TYPE_ZIP]);
$fileSizeValidator = new FileSize(System::getEnv('_APP_COMPUTE_SIZE_LIMIT', '30000000'));
$upload = new Upload();
@@ -172,7 +172,9 @@ class Create extends Action
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
$metadata = ['content_type' => $deviceForLocal->getFileMimeType($fileTmpName)];
\var_dump($metadata);
if (!$deployment->isEmpty()) {
\var_dump("Setting");
$chunks = $deployment->getAttribute('chunksTotal', 1);
$metadata = $deployment->getAttribute('metadata', []);
if ($chunk === -1) {
@@ -206,6 +208,7 @@ class Create extends Action
$fileSize = $deviceForFunctions->getFileSize($path);
if ($deployment->isEmpty()) {
\var_dump("Creating");
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
@@ -249,6 +252,7 @@ class Create extends Action
]))
);
} else {
\var_dump("updating");
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, $deployment->setAttribute('size', $fileSize)->setAttribute('metadata', $metadata));
}
@@ -259,6 +263,7 @@ class Create extends Action
->setDeployment($deployment);
} else {
if ($deployment->isEmpty()) {
\var_dump("Creating 2");
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
+29 -8
View File
@@ -12,9 +12,6 @@ trait SitesBase
{
use Async;
protected string $stdout = '';
protected string $stderr = '';
protected function setupSite(mixed $params): string
{
$site = $this->client->call(Client::METHOD_POST, '/sites', array_merge([
@@ -204,18 +201,42 @@ trait SitesBase
return $logs;
}
protected function packageSite(string $site): CURLFile
protected function packageSite(string $site, string $format = 'gzip'): CURLFile
{
$extension = '';
$command = '';
$header = '';
switch ($format) {
case 'gzip':
$extension = 'tar.gz';
$command = 'tar --exclude code.tar.gz -czf code.tar.gz .';
$header = 'application/x-gzip';
break;
case 'zip':
$extension = 'zip';
$command = 'zip -x code.zip -r code.zip .';
$header = 'application/zip';
break;
default:
throw new \Exception('Invalid package format');
}
$folderPath = realpath(__DIR__ . '/../../../resources/sites') . "/$site";
$tarPath = "$folderPath/code.tar.gz";
$filePath = "$folderPath/code." . $extension;
Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
$stdout = '';
$stderr = '';
$exitCode = Console::execute("cd $folderPath && " . $command, '', $stdout, $stderr);
if (filesize($tarPath) > 1024 * 1024 * 5) {
$this->assertEquals(0, $exitCode);
$this->assertEmpty($stderr);
if (filesize($filePath) > 1024 * 1024 * 5) {
throw new \Exception('Code package is too large. Use the chunked upload method instead.');
}
return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath));
return new CURLFile($filePath, $header, \basename($filePath));
}
protected function createDeployment(string $siteId, mixed $params = []): mixed
@@ -1346,5 +1346,46 @@ class SitesCustomServerTest extends Scope
$this->cleanupSite($site['body']['$id']);
}
public function testSiteZipDeployment(): void
{
$siteId = $this->setupSite([
'siteId' => ID::unique(),
'name' => 'A site',
'framework' => 'other',
'adapter' => 'static',
'buildRuntime' => 'static-1',
'outputDirectory' => './',
'buildCommand' => '',
'installCommand' => '',
'fallbackFile' => '',
]);
$this->assertNotEmpty($siteId);
$deploymentId = $this->setupDeployment($siteId, [
'code' => $this->packageSite('static', 'zip'),
'activate' => 'true'
]);
$this->assertNotEmpty($deploymentId);
$domain = $this->getSiteDomain($siteId);
$this->assertNotEmpty($domain);
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
$response = $proxyClient->call(Client::METHOD_GET, '/', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
]));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertStringContainsString("Hello Appwrite", $response['body']);
$this->cleanupSite($siteId);
}
// TODO: Add tests for deletion of resources when site is deleted
}
Binary file not shown.