mirror of
https://github.com/vitodeploy/vito.git
synced 2025-07-03 06:56:15 +00:00
support S3 compatible storage providers (#401)
This commit is contained in:
@ -3,36 +3,31 @@
|
||||
namespace App\SSH\Storage;
|
||||
|
||||
use App\Exceptions\SSHCommandError;
|
||||
use App\Models\Server;
|
||||
use App\Models\StorageProvider;
|
||||
use App\Exceptions\SSHError;
|
||||
use App\SSH\HasS3Storage;
|
||||
use App\SSH\HasScripts;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class S3 extends S3AbstractStorage
|
||||
class S3 extends AbstractStorage
|
||||
{
|
||||
use HasS3Storage, HasScripts;
|
||||
|
||||
public function __construct(Server $server, StorageProvider $storageProvider)
|
||||
{
|
||||
parent::__construct($server, $storageProvider);
|
||||
$this->setBucketRegion($this->storageProvider->credentials['region']);
|
||||
$this->setApiUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHCommandError
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function upload(string $src, string $dest): array
|
||||
{
|
||||
/** @var \App\StorageProviders\S3 $provider */
|
||||
$provider = $this->storageProvider->provider();
|
||||
|
||||
$uploadCommand = $this->getScript('s3/upload.sh', [
|
||||
'src' => $src,
|
||||
'bucket' => $this->storageProvider->credentials['bucket'],
|
||||
'dest' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$dest),
|
||||
'key' => $this->storageProvider->credentials['key'],
|
||||
'secret' => $this->storageProvider->credentials['secret'],
|
||||
'region' => $this->getBucketRegion(),
|
||||
'endpoint' => $this->getApiUrl(),
|
||||
'region' => $this->storageProvider->credentials['region'],
|
||||
'endpoint' => $provider->getApiUrl(),
|
||||
]);
|
||||
|
||||
$upload = $this->server->ssh()->exec($uploadCommand, 'upload-to-s3');
|
||||
@ -49,20 +44,25 @@ public function upload(string $src, string $dest): array
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHCommandError
|
||||
* @throws SSHError
|
||||
*/
|
||||
public function download(string $src, string $dest): void
|
||||
{
|
||||
/** @var \App\StorageProviders\S3 $provider */
|
||||
$provider = $this->storageProvider->provider();
|
||||
|
||||
$downloadCommand = $this->getScript('s3/download.sh', [
|
||||
'src' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$src),
|
||||
'dest' => $dest,
|
||||
'bucket' => $this->storageProvider->credentials['bucket'],
|
||||
'key' => $this->storageProvider->credentials['key'],
|
||||
'secret' => $this->storageProvider->credentials['secret'],
|
||||
'region' => $this->getBucketRegion(),
|
||||
'endpoint' => $this->getApiUrl(),
|
||||
'region' => $this->storageProvider->credentials['region'],
|
||||
'endpoint' => $provider->getApiUrl(),
|
||||
]);
|
||||
|
||||
Log::info('Downloading from S3', ['command' => $downloadCommand]);
|
||||
|
||||
$download = $this->server->ssh()->exec($downloadCommand, 'download-from-s3');
|
||||
|
||||
if (! str_contains($download, 'Download successful')) {
|
||||
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\SSH\Storage;
|
||||
|
||||
abstract class S3AbstractStorage extends AbstractStorage
|
||||
{
|
||||
protected ?string $apiUrl = null;
|
||||
|
||||
protected ?string $bucketRegion = null;
|
||||
|
||||
public function getApiUrl(): string
|
||||
{
|
||||
return $this->apiUrl;
|
||||
}
|
||||
|
||||
public function setApiUrl(?string $region = null): void
|
||||
{
|
||||
$this->bucketRegion = $region ?? $this->bucketRegion;
|
||||
$this->apiUrl = "https://s3.{$this->bucketRegion}.amazonaws.com";
|
||||
}
|
||||
|
||||
// Getter and Setter for $bucketRegion
|
||||
public function getBucketRegion(): string
|
||||
{
|
||||
return $this->bucketRegion;
|
||||
}
|
||||
|
||||
public function setBucketRegion(string $region): void
|
||||
{
|
||||
$this->bucketRegion = $region;
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\SSH\Storage;
|
||||
|
||||
use App\Exceptions\SSHCommandError;
|
||||
use App\Models\Server;
|
||||
use App\Models\StorageProvider;
|
||||
use App\SSH\HasS3Storage;
|
||||
use App\SSH\HasScripts;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Wasabi extends S3AbstractStorage
|
||||
{
|
||||
use HasS3Storage, HasScripts;
|
||||
|
||||
public function __construct(Server $server, StorageProvider $storageProvider)
|
||||
{
|
||||
parent::__construct($server, $storageProvider);
|
||||
$this->setBucketRegion($this->storageProvider->credentials['region']);
|
||||
$this->setApiUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHCommandError
|
||||
*/
|
||||
public function upload(string $src, string $dest): array
|
||||
{
|
||||
$uploadCommand = $this->getScript('wasabi/upload.sh', [
|
||||
'src' => $src,
|
||||
'bucket' => $this->storageProvider->credentials['bucket'],
|
||||
'dest' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$dest),
|
||||
'key' => $this->storageProvider->credentials['key'],
|
||||
'secret' => $this->storageProvider->credentials['secret'],
|
||||
'region' => $this->storageProvider->credentials['region'],
|
||||
'endpoint' => $this->getApiUrl(),
|
||||
]);
|
||||
|
||||
$upload = $this->server->ssh()->exec($uploadCommand, 'upload-to-wasabi');
|
||||
|
||||
if (str_contains($upload, 'Error') || ! str_contains($upload, 'upload:')) {
|
||||
Log::error('Failed to upload to wasabi', ['output' => $upload]);
|
||||
throw new SSHCommandError('Failed to upload to wasabi: '.$upload);
|
||||
}
|
||||
|
||||
return [
|
||||
'size' => null, // You can parse the size from the output if needed
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws SSHCommandError
|
||||
*/
|
||||
public function download(string $src, string $dest): void
|
||||
{
|
||||
$downloadCommand = $this->getScript('wasabi/download.sh', [
|
||||
'src' => $this->prepareS3Path($this->storageProvider->credentials['path'].'/'.$src),
|
||||
'dest' => $dest,
|
||||
'bucket' => $this->storageProvider->credentials['bucket'],
|
||||
'key' => $this->storageProvider->credentials['key'],
|
||||
'secret' => $this->storageProvider->credentials['secret'],
|
||||
'region' => $this->storageProvider->credentials['region'],
|
||||
'endpoint' => $this->getApiUrl(),
|
||||
]);
|
||||
|
||||
$download = $this->server->ssh()->exec($downloadCommand, 'download-from-wasabi');
|
||||
|
||||
if (! str_contains($download, 'Download successful')) {
|
||||
Log::error('Failed to download from wasabi', ['output' => $download]);
|
||||
throw new SSHCommandError('Failed to download from wasabi: '.$download);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @TODO Implement delete method
|
||||
*/
|
||||
public function delete(string $path): void {}
|
||||
|
||||
public function setApiUrl(?string $region = null): void
|
||||
{
|
||||
$this->bucketRegion = $region ?? $this->bucketRegion;
|
||||
$this->apiUrl = "https://{$this->storageProvider->credentials['bucket']}.s3.{$this->getBucketRegion()}.wasabisys.com";
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Configure AWS CLI with provided credentials
|
||||
/usr/local/bin/aws configure set aws_access_key_id "__key__"
|
||||
/usr/local/bin/aws configure set aws_secret_access_key "__secret__"
|
||||
|
||||
# Use the provided endpoint in the correct format
|
||||
ENDPOINT="__endpoint__"
|
||||
BUCKET="__bucket__"
|
||||
REGION="__region__"
|
||||
|
||||
# Ensure that DEST does not have a trailing slash
|
||||
SRC="__src__"
|
||||
DEST="__dest__"
|
||||
|
||||
# Download the file from S3
|
||||
echo "Downloading s3://__bucket____src__ to __dest__"
|
||||
download_output=$(/usr/local/bin/aws s3 cp "s3://$BUCKET/$SRC" "$DEST" --endpoint-url="$ENDPOINT" --region "$REGION" 2>&1)
|
||||
download_exit_code=$?
|
||||
|
||||
# Log output and exit code
|
||||
echo "Download command output: $download_output"
|
||||
echo "Download command exit code: $download_exit_code"
|
||||
|
||||
# Check if the download was successful
|
||||
if [ $download_exit_code -eq 0 ]; then
|
||||
echo "Download successful"
|
||||
else
|
||||
echo "Download failed"
|
||||
exit 1
|
||||
fi
|
@ -1,59 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if AWS CLI is installed
|
||||
if ! command -v aws &> /dev/null
|
||||
then
|
||||
echo "AWS CLI is not installed. Installing..."
|
||||
|
||||
# Detect system architecture
|
||||
ARCH=$(uname -m)
|
||||
if [ "$ARCH" == "x86_64" ]; then
|
||||
CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip"
|
||||
elif [ "$ARCH" == "aarch64" ]; then
|
||||
CLI_URL="https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip"
|
||||
else
|
||||
echo "Unsupported architecture: $ARCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Download and install AWS CLI
|
||||
sudo curl "$CLI_URL" -o "awscliv2.zip"
|
||||
sudo unzip awscliv2.zip
|
||||
sudo ./aws/install --update
|
||||
sudo rm -rf awscliv2.zip aws
|
||||
|
||||
echo "AWS CLI installation completed."
|
||||
else
|
||||
echo "AWS CLI is already installed."
|
||||
aws --version
|
||||
fi
|
||||
|
||||
# Configure AWS CLI with provided credentials
|
||||
/usr/local/bin/aws configure set aws_access_key_id "__key__"
|
||||
/usr/local/bin/aws configure set aws_secret_access_key "__secret__"
|
||||
|
||||
# Use the provided endpoint in the correct format
|
||||
ENDPOINT="__endpoint__"
|
||||
BUCKET="__bucket__"
|
||||
REGION="__region__"
|
||||
|
||||
# Ensure that DEST does not have a trailing slash
|
||||
SRC="__src__"
|
||||
DEST="__dest__"
|
||||
|
||||
# Upload the file
|
||||
echo "Uploading __src__ to s3://$BUCKET/$DEST"
|
||||
upload_output=$(/usr/local/bin/aws s3 cp "$SRC" "s3://$BUCKET/$DEST" --endpoint-url="$ENDPOINT" --region "$REGION" 2>&1)
|
||||
upload_exit_code=$?
|
||||
|
||||
# Log output and exit code
|
||||
echo "Upload command output: $upload_output"
|
||||
echo "Upload command exit code: $upload_exit_code"
|
||||
|
||||
# Check if the upload was successful
|
||||
if [ $upload_exit_code -eq 0 ]; then
|
||||
echo "Upload successful"
|
||||
else
|
||||
echo "Upload failed"
|
||||
exit 1
|
||||
fi
|
Reference in New Issue
Block a user