mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Implement ZIP site deployment
This commit is contained in:
@@ -30,6 +30,9 @@ RUN \
|
||||
|
||||
RUN apk add libwebp
|
||||
|
||||
# TODO: Move to appwrite/docker-base
|
||||
RUN apk add zip
|
||||
|
||||
WORKDIR /usr/src/code
|
||||
|
||||
COPY --from=composer /usr/local/src/vendor /usr/src/code/vendor
|
||||
|
||||
@@ -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, 'zip']); // TODO: Move 'zip' to Storage library
|
||||
$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' => [
|
||||
|
||||
@@ -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([
|
||||
@@ -164,18 +161,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
|
||||
|
||||
@@ -1088,5 +1088,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.
Reference in New Issue
Block a user