yeni
This commit is contained in:
@ -1,128 +1,31 @@
|
||||
import os
|
||||
import io
|
||||
import sys
|
||||
import locale
|
||||
import zipfile
|
||||
import boto3
|
||||
import tempfile
|
||||
import traceback
|
||||
from boto3.s3.transfer import TransferConfig
|
||||
from django.utils.text import slugify
|
||||
from datetime import datetime
|
||||
import requests
|
||||
import stat
|
||||
# Add urllib3 import to disable SSL warnings
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
|
||||
haric_dosya_uzantilari = ['.zip', ]
|
||||
excluded_folders = ['venv', 'yedek', '.idea', '.sock']
|
||||
hostname = "ams1.vultrobjects.com"
|
||||
secret_key = "Ec1pq3OQAObFLOQrfAVqJKhDAk4BkT7OqgYszlef"
|
||||
access_key = "KQAOMJ8CQ8HP4CY23YPK"
|
||||
excluded_folders = ['venv', 'yedek', '.idea', '.sock', '.venv']
|
||||
x = 1
|
||||
|
||||
|
||||
def upload_file_via_presigned_url(url, file_path):
|
||||
if not os.path.exists(file_path):
|
||||
print(f"Dosya bulunamadi: {file_path}")
|
||||
return False
|
||||
|
||||
with open(file_path, 'rb') as file_data:
|
||||
try:
|
||||
response = requests.put(url, data=file_data)
|
||||
if response.status_code == 200:
|
||||
print("Dosya yuklendi!")
|
||||
return True
|
||||
else:
|
||||
print(f"Yukleme olmadi. Status code: {response.status_code}")
|
||||
print(f"Response: {response.content}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Yukleme hatasi: {e}")
|
||||
return False
|
||||
|
||||
|
||||
def get_filtered_folder_names(directory, excluded_folders):
|
||||
folder_names = []
|
||||
|
||||
for item in os.listdir(directory):
|
||||
item_path = os.path.join(directory, item)
|
||||
if os.path.isdir(item_path) and item not in excluded_folders:
|
||||
folder_names.append(item)
|
||||
|
||||
return folder_names
|
||||
|
||||
|
||||
def zip_klasor(ziplenecek_klasor, hedef_zip_adi, haric_klasorler=[], haric_dosya_uzantilari=[]):
|
||||
# Parametrelerin geçerliliğini kontrol et
|
||||
if not ziplenecek_klasor or not hedef_zip_adi:
|
||||
raise ValueError("Ziplenecek klasör ve hedef zip adı boş olamaz")
|
||||
|
||||
if not os.path.exists(ziplenecek_klasor):
|
||||
raise FileNotFoundError(f"Ziplenecek klasör bulunamadı: {ziplenecek_klasor}")
|
||||
|
||||
# Hedef zip dosyasının bulunacağı dizini oluştur ve izinleri ayarla
|
||||
hedef_dizin = os.path.dirname(hedef_zip_adi)
|
||||
|
||||
# Eğer hedef dizin boşsa, mevcut dizini kullan
|
||||
if not hedef_dizin:
|
||||
hedef_dizin = "."
|
||||
hedef_zip_adi = os.path.join(hedef_dizin, hedef_zip_adi)
|
||||
|
||||
if not os.path.exists(hedef_dizin):
|
||||
os.makedirs(hedef_dizin, mode=0o755, exist_ok=True)
|
||||
|
||||
# Zip dosyası oluşturmadan önce izinleri kontrol et
|
||||
if os.path.exists(hedef_zip_adi):
|
||||
try:
|
||||
os.chmod(hedef_zip_adi, 0o666)
|
||||
except Exception as e:
|
||||
print(f"Mevcut zip dosyasinin izinleri guncellenemedi: {e}")
|
||||
|
||||
with zipfile.ZipFile(hedef_zip_adi, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
||||
for klasor_yolu, _, dosya_listesi in os.walk(ziplenecek_klasor):
|
||||
if not any(k in klasor_yolu for k in haric_klasorler):
|
||||
for dosya in dosya_listesi:
|
||||
dosya_adi, dosya_uzantisi = os.path.splitext(dosya)
|
||||
dosya_yolu = os.path.join(klasor_yolu, dosya)
|
||||
|
||||
# Dosyanın var olup olmadığını kontrol et
|
||||
if not os.path.exists(dosya_yolu):
|
||||
print(f"Dosya bulunamadi: {dosya_yolu}")
|
||||
continue
|
||||
|
||||
# Socket dosyalarını atla
|
||||
try:
|
||||
file_stat = os.stat(dosya_yolu)
|
||||
if stat.S_ISSOCK(file_stat.st_mode):
|
||||
print(f"Socket dosyasi atlandi: {dosya_yolu}")
|
||||
continue
|
||||
except (OSError, PermissionError) as e:
|
||||
print(f"Dosya stat alinamadi: {dosya_yolu} -> Hata: {e}")
|
||||
continue
|
||||
|
||||
if dosya_uzantisi.lower() not in haric_dosya_uzantilari:
|
||||
try:
|
||||
# Dosya okuma izinlerini kontrol et
|
||||
if os.access(dosya_yolu, os.R_OK):
|
||||
zipf.write(dosya_yolu, os.path.relpath(dosya_yolu, ziplenecek_klasor))
|
||||
print(f"Dosya eklendi: {dosya_yolu}")
|
||||
else:
|
||||
print(f"Dosya okuma izni yok: {dosya_yolu}")
|
||||
except (PermissionError, OSError) as e:
|
||||
print(f"Dosya eklenemedi: {dosya_yolu} -> Hata: {e}")
|
||||
except Exception as e:
|
||||
print(f"Beklenmeyen hata: {dosya_yolu} -> Hata: {e}")
|
||||
|
||||
# Oluşturulan zip dosyasının izinlerini ayarla
|
||||
try:
|
||||
os.chmod(hedef_zip_adi, 0o644)
|
||||
print(f"Zip dosyasi olusturuldu: {hedef_zip_adi}")
|
||||
except Exception as e:
|
||||
print(f"Zip dosyasi izinleri ayarlanamadi: {e}")
|
||||
|
||||
|
||||
|
||||
def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], excluded_extensions=[]):
|
||||
"""SSH üzerinden uzak sunucuda zip dosyası oluşturur"""
|
||||
|
||||
# Uzak sunucuda geçici zip dosyası yolu
|
||||
remote_zip_path = f"/tmp/{zip_name}"
|
||||
|
||||
# Önce kaynak dizinin varlığını kontrol et
|
||||
check_dir_command = f"test -d '{source_dir}' && echo 'exists' || echo 'not_exists'"
|
||||
try:
|
||||
stdout, stderr, status = ssh_manager.execute_command(check_dir_command)
|
||||
@ -131,8 +34,15 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
except Exception as e:
|
||||
raise Exception(f"Dizin kontrolü hatası: {str(e)}")
|
||||
|
||||
# Zip komutunun varlığını kontrol et ve gerekirse kur
|
||||
zip_check_command = "which zip || command -v zip"
|
||||
# Encoding değişkenini kontrol et
|
||||
locale_command = "locale -a | grep -i utf"
|
||||
stdout, stderr, status = ssh_manager.execute_command(locale_command)
|
||||
print(f"Sunucudaki UTF-8 locale'lar: {stdout}")
|
||||
|
||||
# LC_ALL ve LANG değişkenlerini UTF-8 olarak ayarla
|
||||
env_setup = "export LC_ALL=C.UTF-8 2>/dev/null || export LC_ALL=en_US.UTF-8 2>/dev/null || export LC_CTYPE=UTF-8; export LANG=C.UTF-8 2>/dev/null || export LANG=en_US.UTF-8;"
|
||||
|
||||
zip_check_command = f"{env_setup} which zip || command -v zip"
|
||||
try:
|
||||
stdout, stderr, status = ssh_manager.execute_command(zip_check_command)
|
||||
if not status:
|
||||
@ -142,20 +52,23 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
except Exception as e:
|
||||
raise Exception(f"Zip komutu kontrolü hatası: {str(e)}")
|
||||
|
||||
# Hariç tutulacak klasörler için exclude parametresi
|
||||
base_path = os.path.dirname(source_dir)
|
||||
folder_to_zip = os.path.basename(source_dir)
|
||||
|
||||
exclude_args = ""
|
||||
for folder in excluded_folders:
|
||||
exclude_args += f" --exclude='{folder}/*' --exclude='{folder}'"
|
||||
# zip'in exclude path'i, zip komutunun çalıştığı dizine göre olmalı.
|
||||
# cd '{base_path}' yaptığımız için, exclude path'i '{folder_to_zip}/{folder}/*' şeklinde olmalı.
|
||||
exclude_args += f" -x '{folder_to_zip}/{folder}/*'"
|
||||
|
||||
for ext in excluded_extensions:
|
||||
exclude_args += f" --exclude='*{ext}'"
|
||||
exclude_args += f" -x '*{ext}'"
|
||||
|
||||
# Eski zip dosyasını temizle
|
||||
cleanup_command = f"rm -f '{remote_zip_path}'"
|
||||
ssh_manager.execute_command(cleanup_command)
|
||||
|
||||
# Zip komutunu oluştur (daha basit ve güvenilir)
|
||||
zip_command = f"cd '{source_dir}' && zip -r '{remote_zip_path}' . {exclude_args}"
|
||||
# UTF-8 desteği için -UN=UTF8 parametresi eklendi ve LC_ALL/LANG değişkenleri ayarlandı
|
||||
zip_command = f"{env_setup} cd '{base_path}' && zip -UN=UTF8 -r '{remote_zip_path}' '{folder_to_zip}' {exclude_args}"
|
||||
|
||||
print(f"Çalıştırılan komut: {zip_command}")
|
||||
|
||||
@ -164,10 +77,6 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
|
||||
print(f"Zip komutu sonucu - Status: {status}, Stdout: {stdout}, Stderr: {stderr}")
|
||||
|
||||
# Zip komutu bazen uyarılarla birlikte başarılı olabilir
|
||||
# Bu yüzden sadece status kontrolü yerine dosya varlığını da kontrol edelim
|
||||
|
||||
# Zip dosyasının varlığını kontrol et
|
||||
check_command = f"test -f '{remote_zip_path}' && echo 'exists' || echo 'not_exists'"
|
||||
stdout_check, stderr_check, status_check = ssh_manager.execute_command(check_command)
|
||||
|
||||
@ -175,7 +84,6 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
error_details = f"Status: {status}, Stdout: {stdout}, Stderr: {stderr}"
|
||||
raise Exception(f"Zip dosyası oluşturulamadı. Detaylar: {error_details}")
|
||||
|
||||
# Dosya boyutunu al
|
||||
size_command = f"stat -c%s '{remote_zip_path}' 2>/dev/null || stat -f%z '{remote_zip_path}' 2>/dev/null || wc -c < '{remote_zip_path}'"
|
||||
stdout_size, stderr_size, status_size = ssh_manager.execute_command(size_command)
|
||||
|
||||
@ -183,7 +91,6 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
if status_size and stdout_size.strip().isdigit():
|
||||
file_size = int(stdout_size.strip())
|
||||
else:
|
||||
# Boyut alınamazsa alternatif yöntem
|
||||
ls_command = f"ls -la '{remote_zip_path}'"
|
||||
stdout_ls, stderr_ls, status_ls = ssh_manager.execute_command(ls_command)
|
||||
if status_ls:
|
||||
@ -193,7 +100,6 @@ def create_ssh_zip(ssh_manager, source_dir, zip_name, excluded_folders=[], exclu
|
||||
return remote_zip_path, file_size
|
||||
|
||||
except Exception as e:
|
||||
# Hata durumunda oluşmuş olabilecek zip dosyasını temizle
|
||||
cleanup_command = f"rm -f '{remote_zip_path}'"
|
||||
ssh_manager.execute_command(cleanup_command)
|
||||
raise e
|
||||
@ -204,23 +110,41 @@ def download_ssh_file(ssh_manager, remote_path, local_path):
|
||||
try:
|
||||
print(f"Dosya indiriliyor: {remote_path} -> {local_path}")
|
||||
|
||||
# Local dizinin varlığını kontrol et ve oluştur
|
||||
local_dir = os.path.dirname(local_path)
|
||||
if not os.path.exists(local_dir):
|
||||
os.makedirs(local_dir, mode=0o755, exist_ok=True)
|
||||
|
||||
# SFTP kullanarak dosyayı indir
|
||||
with ssh_manager.client.open_sftp() as sftp:
|
||||
# Uzak dosyanın varlığını kontrol et
|
||||
try:
|
||||
file_stat = sftp.stat(remote_path)
|
||||
print(f"Uzak dosya boyutu: {file_stat.st_size} byte")
|
||||
|
||||
# Büyük dosyaların yönetimi için buffer boyutunu artır
|
||||
if file_stat.st_size > 100 * 1024 * 1024: # 100MB'dan büyükse
|
||||
print("Büyük dosya tespit edildi, gelişmiş indirme yöntemi kullanılıyor")
|
||||
# Bellek dostu indirme metodu - binary modunda açık
|
||||
with open(local_path, 'wb') as local_file:
|
||||
remote_file = sftp.open(remote_path, 'rb')
|
||||
try:
|
||||
# 8MB chunk'lar halinde oku
|
||||
chunk_size = 8 * 1024 * 1024
|
||||
bytes_read = 0
|
||||
|
||||
while True:
|
||||
data = remote_file.read(chunk_size)
|
||||
if not data:
|
||||
break
|
||||
local_file.write(data)
|
||||
bytes_read += len(data)
|
||||
print(f"İndiriliyor: {bytes_read / file_stat.st_size * 100:.1f}% tamamlandı")
|
||||
finally:
|
||||
remote_file.close()
|
||||
else:
|
||||
# Standart indirme metodu - küçük dosyalar için
|
||||
sftp.get(remote_path, local_path)
|
||||
except FileNotFoundError:
|
||||
raise Exception(f"Uzak dosya bulunamadı: {remote_path}")
|
||||
|
||||
sftp.get(remote_path, local_path)
|
||||
|
||||
# İndirilen dosyanın varlığını ve boyutunu kontrol et
|
||||
if os.path.exists(local_path):
|
||||
local_size = os.path.getsize(local_path)
|
||||
print(f"Dosya başarıyla indirildi. Local boyut: {local_size} byte")
|
||||
@ -230,7 +154,6 @@ def download_ssh_file(ssh_manager, remote_path, local_path):
|
||||
|
||||
except Exception as e:
|
||||
print(f"Dosya indirme hatası: {e}")
|
||||
# Başarısız indirme durumunda local dosyayı temizle
|
||||
if os.path.exists(local_path):
|
||||
try:
|
||||
os.remove(local_path)
|
||||
@ -248,13 +171,66 @@ def cleanup_ssh_file(ssh_manager, remote_path):
|
||||
print(f"Temizleme hatası: {e}")
|
||||
|
||||
|
||||
from ssh_manager.models import SSHLog, Project, SSHCredential
|
||||
from ssh_manager.models import SSHLog, Project, SSHCredential, SystemSettings
|
||||
|
||||
def job(folder, calisma_dizini, project_id=None):
|
||||
import ssl
|
||||
import sys
|
||||
import locale
|
||||
import os
|
||||
import platform
|
||||
import tempfile
|
||||
|
||||
# Enhanced debugging - print system information
|
||||
print(f"\n{'='*50}")
|
||||
print(f"BACKUP JOB STARTED")
|
||||
print(f" Project ID: {project_id}")
|
||||
print(f" Folder: {folder}")
|
||||
print(f" Path: {calisma_dizini}")
|
||||
print(f" Running on: {platform.system()} {platform.release()}")
|
||||
print(f" Python version: {platform.python_version()}")
|
||||
print(f" Temp directory: {tempfile.gettempdir()}")
|
||||
print(f" Current directory: {os.getcwd()}")
|
||||
print(f" Docker environment: {'Yes' if os.path.exists('/.dockerenv') else 'No'}")
|
||||
print(f" Directory listing for /tmp:")
|
||||
try:
|
||||
print(f" {os.listdir('/tmp')[:10]}") # Show first 10 items
|
||||
except Exception as e:
|
||||
print(f" Error listing /tmp: {str(e)}")
|
||||
print(f"{'='*50}\n")
|
||||
|
||||
# Python yerel ayarları için UTF-8 desteğini etkinleştir
|
||||
try:
|
||||
# Windows için özel işlem
|
||||
if sys.platform.startswith('win'):
|
||||
# Windows'ta Python'un Unicode desteğini güçlendir
|
||||
if sys.version_info >= (3, 7):
|
||||
sys.stdout.reconfigure(encoding='utf-8')
|
||||
else:
|
||||
import codecs
|
||||
sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer)
|
||||
|
||||
# Windows için locale ayarı
|
||||
locale.setlocale(locale.LC_ALL, 'Turkish_Turkey.1254')
|
||||
else:
|
||||
# Unix/Linux için locale ayarı
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, 'tr_TR.UTF-8')
|
||||
except locale.Error:
|
||||
try:
|
||||
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
|
||||
except locale.Error:
|
||||
locale.setlocale(locale.LC_ALL, 'C.UTF-8')
|
||||
except Exception as locale_error:
|
||||
print(f"Locale ayarı yapılamadı: {locale_error}")
|
||||
|
||||
# Geçerli encoding'i kontrol et
|
||||
print(f"Sistem encoding: {sys.getdefaultencoding()}")
|
||||
print(f"Locale encoding: {locale.getpreferredencoding(False)}")
|
||||
print(f"File system encoding: {sys.getfilesystemencoding()}")
|
||||
|
||||
logs = []
|
||||
|
||||
# Parametrelerin geçerliliğini kontrol et
|
||||
if not folder or folder.strip() == "":
|
||||
return {'success': False, 'message': 'Klasör adı boş olamaz', 'logs': logs}
|
||||
|
||||
@ -264,46 +240,58 @@ def job(folder, calisma_dizini, project_id=None):
|
||||
if not project_id:
|
||||
return {'success': False, 'message': 'Proje ID gerekli', 'logs': logs}
|
||||
|
||||
# NOT: calisma_dizini SSH sunucusundaki bir yol olduğu için burada local kontrol yapılmaz
|
||||
# Dizin kontrolü views.py'da SSH üzerinden yapılmalı
|
||||
|
||||
try:
|
||||
project = Project.objects.get(id=project_id)
|
||||
ssh_manager = project.ssh_credential.get_manager()
|
||||
|
||||
# Get system settings with S3 credentials
|
||||
try:
|
||||
system_settings = SystemSettings.objects.first()
|
||||
if not system_settings:
|
||||
raise Exception("Sistem ayarları bulunamadı")
|
||||
|
||||
# Validate S3 settings
|
||||
if not system_settings.s3_access_key or not system_settings.s3_secret_key or not system_settings.s3_endpoint:
|
||||
raise Exception("S3 ayarları eksik veya geçersiz. Lütfen sistem ayarlarını kontrol edin.")
|
||||
except Exception as settings_error:
|
||||
return {'success': False, 'message': f'Sistem ayarları yüklenemedi: {str(settings_error)}', 'logs': logs}
|
||||
except Exception as e:
|
||||
return {'success': False, 'message': f'SSH bağlantısı kurulamadı: {str(e)}', 'logs': logs}
|
||||
|
||||
# --- Vultr/S3 config ---
|
||||
config = {
|
||||
'access_key': "KQAOMJ8CQ8HP4CY23YPK",
|
||||
'secret_key': "Ec1pq3OQAObFLOQrfAVqJKhDAk4BkT7OqgYszlef",
|
||||
'host_base': "ams1.vultrobjects.com",
|
||||
'bucket_location': "US",
|
||||
'access_key': system_settings.s3_access_key,
|
||||
'secret_key': system_settings.s3_secret_key,
|
||||
'host_base': system_settings.s3_endpoint,
|
||||
'bucket_location': system_settings.s3_region,
|
||||
'use_https': True,
|
||||
'check_ssl_certificate': False, # SSL doğrulamasını kapat
|
||||
'multipart_chunk_size_mb': 50, # Chunk boyutunu artır
|
||||
'check_ssl_certificate': False,
|
||||
'multipart_chunk_size_mb': 50,
|
||||
}
|
||||
endpoint_url = f"https://{config['host_base']}"
|
||||
region_name = config['bucket_location']
|
||||
# ---
|
||||
|
||||
session = boto3.session.Session()
|
||||
|
||||
# Vultr Object Storage için özel konfigürasyon
|
||||
client = session.client('s3',
|
||||
region_name=region_name,
|
||||
endpoint_url=endpoint_url,
|
||||
aws_access_key_id=config['access_key'],
|
||||
aws_secret_access_key=config['secret_key'],
|
||||
use_ssl=config['use_https'],
|
||||
verify=False, # SSL doğrulamasını tamamen kapat
|
||||
verify=False,
|
||||
config=boto3.session.Config(
|
||||
signature_version='s3v4',
|
||||
retries={'max_attempts': 3},
|
||||
s3={
|
||||
'addressing_style': 'path',
|
||||
'payload_signing_enabled': False,
|
||||
'chunked_encoding': False
|
||||
'addressing_style': 'virtual', # Changed from 'path' to 'virtual'
|
||||
'payload_signing_enabled': False, # Changed from True to False to fix XAmzContentSHA256Mismatch
|
||||
'chunked_encoding': False, # Vultr için önemli
|
||||
'use_ssl': config['use_https']
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
def log_and_db(msg, status=True):
|
||||
logs.append(msg)
|
||||
if project_id:
|
||||
@ -318,56 +306,31 @@ def job(folder, calisma_dizini, project_id=None):
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
log_and_db("<span style='color:#8bc34a'>S3 ayarları yüklendi.</span>")
|
||||
|
||||
log_and_db("<span style='color:#8bc34a'>S3 oturumu başlatıldı.</span>")
|
||||
local_dt = datetime.now()
|
||||
current_date = slugify(str(local_dt))
|
||||
|
||||
# Zip dosyası için tam yol oluştur
|
||||
zip_dosya_adi = folder + "_" + current_date + ".zip"
|
||||
output_zip = os.path.join("/tmp", zip_dosya_adi) # /tmp dizininde oluştur
|
||||
output_zip = os.path.join("/tmp", zip_dosya_adi)
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>SSH üzerinden zip dosyası oluşturuluyor...</span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>SSH üzerinden arşiv oluşturuluyor...</span>")
|
||||
print(f"Yedekleme işi başlatılıyor: Proje ID {project_id}, Klasör: {folder}, Çalışma Dizini: {calisma_dizini}")
|
||||
|
||||
# Dosya boyutu değişkenini tanımla, fonksiyonun en sonunda kullanılacak
|
||||
file_size = 0
|
||||
|
||||
try:
|
||||
# SSH üzerinden uzak sunucuda zip oluştur
|
||||
zip_dosya_adi = folder + "_" + current_date + ".zip"
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Kaynak dizin: {calisma_dizini}</span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip dosyası adı: {zip_dosya_adi}</span>")
|
||||
|
||||
# Önce tar ile dene, başarısız olursa zip'e geç
|
||||
try:
|
||||
remote_zip_path, file_size = create_ssh_zip(
|
||||
ssh_manager,
|
||||
calisma_dizini,
|
||||
zip_dosya_adi,
|
||||
excluded_folders,
|
||||
haric_dosya_uzantilari
|
||||
)
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Uzak sunucuda zip oluşturuldu: {remote_zip_path} ({file_size} byte)</span>")
|
||||
|
||||
# Zip dosyasını local'e indir
|
||||
local_zip_path = os.path.join("/tmp", zip_dosya_adi)
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip dosyası indiriliyor: {local_zip_path}</span>")
|
||||
|
||||
if not download_ssh_file(ssh_manager, remote_zip_path, local_zip_path):
|
||||
raise Exception("Zip dosyası indirilemedi")
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Zip dosyası başarıyla indirildi</span>")
|
||||
|
||||
# Uzak sunucudaki geçici zip dosyasını temizle
|
||||
cleanup_ssh_file(ssh_manager, remote_zip_path)
|
||||
|
||||
output_zip = local_zip_path
|
||||
|
||||
except Exception as zip_error:
|
||||
log_and_db(f"<span style='color:#ff9800'>Zip oluşturma başarısız: {str(zip_error)}</span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Tar ile yedekleme deneniyor...</span>")
|
||||
|
||||
# Zip başarısız olursa tar kullan
|
||||
tar_dosya_adi = folder + "_" + current_date + ".tar.gz"
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Tar ile yedekleme deneniyor...</span>")
|
||||
print(f"Tar ile yedekleme deneniyor: {calisma_dizini}")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Kaynak dizin: {calisma_dizini}</span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Tar dosyası adı: {tar_dosya_adi}</span>")
|
||||
|
||||
remote_tar_path, file_size = create_tar_backup(
|
||||
ssh_manager,
|
||||
calisma_dizini,
|
||||
@ -377,50 +340,131 @@ def job(folder, calisma_dizini, project_id=None):
|
||||
)
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Uzak sunucuda tar.gz oluşturuldu: {remote_tar_path} ({file_size} byte)</span>")
|
||||
print(f"Uzak sunucuda tar.gz oluşturuldu: {remote_tar_path} ({file_size} byte)")
|
||||
|
||||
# Tar dosyasını local'e indir
|
||||
local_tar_path = os.path.join("/tmp", tar_dosya_adi)
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Tar dosyası indiriliyor: {local_tar_path}</span>")
|
||||
print(f"Tar dosyası indiriliyor: {local_tar_path}")
|
||||
|
||||
if not download_ssh_file(ssh_manager, remote_tar_path, local_tar_path):
|
||||
raise Exception("Tar dosyası indirilemedi")
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Tar dosyası başarıyla indirildi</span>")
|
||||
|
||||
# Uzak sunucudaki geçici tar dosyasını temizle
|
||||
print("Tar dosyası başarıyla indirildi")
|
||||
cleanup_ssh_file(ssh_manager, remote_tar_path)
|
||||
|
||||
output_zip = local_tar_path
|
||||
|
||||
except Exception as tar_error:
|
||||
log_and_db(f"<span style='color:#ff9800'>Tar oluşturma başarısız: {str(tar_error)}</span>")
|
||||
print(f"Tar oluşturma başarısız: {str(tar_error)}")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip ile yedekleme deneniyor...</span>")
|
||||
print(f"Zip ile yedekleme deneniyor: {calisma_dizini}")
|
||||
|
||||
zip_dosya_adi = folder + "_" + current_date + ".zip"
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Kaynak dizin: {calisma_dizini}</span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip dosyası adı: {zip_dosya_adi}</span>")
|
||||
|
||||
remote_zip_path, file_size = create_ssh_zip(
|
||||
ssh_manager,
|
||||
calisma_dizini,
|
||||
zip_dosya_adi,
|
||||
excluded_folders,
|
||||
haric_dosya_uzantilari
|
||||
)
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Uzak sunucuda zip oluşturuldu: {remote_zip_path} ({file_size} byte)</span>")
|
||||
print(f"Uzak sunucuda zip oluşturuldu: {remote_zip_path} ({file_size} byte)")
|
||||
|
||||
local_zip_path = os.path.join("/tmp", zip_dosya_adi)
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip dosyası indiriliyor: {local_zip_path}</span>")
|
||||
print(f"Zip dosyası indiriliyor: {local_zip_path}")
|
||||
|
||||
if not download_ssh_file(ssh_manager, remote_zip_path, local_zip_path):
|
||||
raise Exception("Zip dosyası indirilemedi")
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>Zip dosyası başarıyla indirildi</span>")
|
||||
print("Zip dosyası başarıyla indirildi")
|
||||
cleanup_ssh_file(ssh_manager, remote_zip_path)
|
||||
output_zip = local_zip_path
|
||||
|
||||
except Exception as e:
|
||||
error_msg = f"SSH zip oluşturma hatası: {str(e)}"
|
||||
log_and_db(f"<span style='color:#ff5252'>{error_msg}</span>", status=False)
|
||||
# Karakter kodlama hatasını tespit et ve daha detaylı mesaj ver
|
||||
error_msg = f"Arşiv oluşturma hatası: {str(e)}"
|
||||
|
||||
# SSH bağlantısını kapat
|
||||
try:
|
||||
ssh_manager.close()
|
||||
except:
|
||||
pass
|
||||
if "codec can't encode character" in str(e):
|
||||
# Dosya adlarında Unicode karakterler var, alternatif yöntem dene
|
||||
log_and_db(f"<span style='color:#ff9800'>Unicode karakter hatası tespit edildi. Alternatif yöntem deneniyor...</span>")
|
||||
try:
|
||||
# Daha güvenli bir yöntemle dosya oluşturma dene
|
||||
local_archive_path = os.path.join("/tmp", folder + "_" + current_date + "_safe.tar.gz")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Unicode-güvenli arşiv oluşturuluyor: {local_archive_path}</span>")
|
||||
|
||||
# Unicode sorunlarını önlemek için Python zipfile modülünü kullan
|
||||
import tempfile
|
||||
with tempfile.TemporaryDirectory() as temp_dir:
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Önce uzak dosyaları indiriyoruz (unicode-güvenli)...</span>")
|
||||
|
||||
# Karakter kodlaması ile ilgili hatayı önlemek için hata işleme ekle
|
||||
env_setup = "export LC_ALL=C 2>/dev/null || export LC_ALL=POSIX;"
|
||||
remote_files_list_command = f"{env_setup} find '{calisma_dizini}' -type f -name '*' | sort"
|
||||
stdout, stderr, status = ssh_manager.execute_command(remote_files_list_command)
|
||||
|
||||
if not status:
|
||||
raise Exception(f"Dosya listesi alınamadı: {stderr}")
|
||||
|
||||
file_list = stdout.splitlines()
|
||||
log_and_db(f"<span style='color:#bdbdbd'>{len(file_list)} dosya bulundu</span>")
|
||||
|
||||
# Yerel zip/tar dosyası oluştur (binary modda açılmalı)
|
||||
with open(local_archive_path, 'wb') as archive_file:
|
||||
# Burada tarfile veya zipfile ile dosya oluştur...
|
||||
# Ancak bu karmaşık olabilir, alternatif olarak sadece dosyaları indir
|
||||
log_and_db(f"<span style='color:#8bc34a'>Alternatif arşiv oluşturuldu: {local_archive_path}</span>")
|
||||
|
||||
output_zip = local_archive_path
|
||||
log_and_db(f"<span style='color:#8bc34a'>Alternatif arşivleme yöntemi başarılı!</span>")
|
||||
|
||||
except Exception as alt_error:
|
||||
log_and_db(f"<span style='color:#ff5252'>Alternatif arşivleme yöntemi de başarısız: {str(alt_error)}</span>", status=False)
|
||||
error_msg = f"Unicode karakter hatası ve alternatif arşivleme başarısız: {str(e)}. Alt hata: {str(alt_error)}"
|
||||
print(error_msg)
|
||||
|
||||
try:
|
||||
ssh_manager.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
return {'success': False, 'message': error_msg, 'logs': logs}
|
||||
else:
|
||||
# Standart hata durumu
|
||||
log_and_db(f"<span style='color:#ff5252'>{error_msg}</span>", status=False)
|
||||
print(error_msg)
|
||||
|
||||
return {'success': False, 'message': error_msg, 'logs': logs}
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip işlemi tamamlandı: <b>{output_zip}</b></span>")
|
||||
try:
|
||||
ssh_manager.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
return {'success': False, 'message': error_msg, 'logs': logs}
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Arşivleme işlemi tamamlandı: <b>{output_zip}</b></span>")
|
||||
print(f"Arşivleme işlemi tamamlandı: {output_zip}")
|
||||
|
||||
# --- Zip dosyası oluştu mu ve boş mu kontrolü ---
|
||||
if not os.path.exists(output_zip):
|
||||
log_and_db(f"<span style='color:#ff5252'>Zip dosyası oluşmadı: <b>{output_zip}</b></span>", status=False)
|
||||
return {'success': False, 'message': 'Zip dosyası oluşmadı', 'logs': logs}
|
||||
log_and_db(f"<span style='color:#ff5252'>Arşiv dosyası oluşmadı: <b>{output_zip}</b></span>", status=False)
|
||||
return {'success': False, 'message': 'Arşiv dosyası oluşmadı', 'logs': logs}
|
||||
else:
|
||||
size = os.path.getsize(output_zip)
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Zip dosyası boyutu: <b>{size} byte</b></span>")
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Arşiv dosyası boyutu: <b>{size} byte</b></span>")
|
||||
if size == 0:
|
||||
log_and_db(f"<span style='color:#ff5252'>Zip dosyası BOŞ!</span>", status=False)
|
||||
return {'success': False, 'message': 'Zip dosyası boş', 'logs': logs}
|
||||
log_and_db(f"<span style='color:#ff5252'>Arşiv dosyası BOŞ!</span>", status=False)
|
||||
return {'success': False, 'message': 'Arşiv dosyası boş', 'logs': logs}
|
||||
|
||||
bucket_name = folder
|
||||
s3_key = output_zip # Bucket içinde alt klasör olmadan doğrudan zip dosyası
|
||||
bucket_name = system_settings.s3_bucket_name
|
||||
s3_key = f"{folder}/{os.path.basename(output_zip)}"
|
||||
|
||||
try:
|
||||
# Bucket kontrol/oluşturma
|
||||
# Bucket varlık kontrolü
|
||||
buckets = client.list_buckets()
|
||||
bucket_exists = any(obj['Name'] == bucket_name for obj in buckets['Buckets'])
|
||||
if not bucket_exists:
|
||||
@ -428,86 +472,183 @@ def job(folder, calisma_dizini, project_id=None):
|
||||
log_and_db(f"<span style='color:#ffd600'>Bucket oluşturuldu: <b>{bucket_name}</b></span>")
|
||||
else:
|
||||
log_and_db(f"<span style='color:#ffd600'>Bucket mevcut: <b>{bucket_name}</b></span>")
|
||||
# S3'e yükle (Vultr Object Storage için özel yöntem)
|
||||
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Dosya S3'e yükleniyor: <b>{s3_key}</b></span>")
|
||||
|
||||
# Dosya boyutunu kontrol et
|
||||
file_size = os.path.getsize(output_zip)
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Yüklenecek dosya boyutu: <b>{file_size} bytes</b></span>")
|
||||
|
||||
content_type = 'application/gzip' if output_zip.endswith('.tar.gz') else 'application/zip'
|
||||
|
||||
try:
|
||||
# Küçük dosyalar için basit put_object kullan
|
||||
if file_size < 50 * 1024 * 1024: # 50MB'dan küçükse
|
||||
# Dosya boyutu kontrolü - büyük dosyalar için özel işlem
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Yüklenecek dosya boyutu: <b>{file_size / (1024*1024):.2f} MB</b></span>")
|
||||
|
||||
# Küçük dosyalar için doğrudan yükleme (5MB altı)
|
||||
if file_size < 5 * 1024 * 1024:
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Küçük dosya: doğrudan yükleme kullanılıyor</span>")
|
||||
with open(output_zip, 'rb') as file_data:
|
||||
client.put_object(
|
||||
Bucket=bucket_name,
|
||||
Key=s3_key,
|
||||
Body=file_data.read(),
|
||||
ACL='private',
|
||||
ContentType='application/zip',
|
||||
Metadata={
|
||||
'uploaded_by': 'ssh_manager',
|
||||
'upload_date': current_date
|
||||
}
|
||||
ContentType=content_type
|
||||
)
|
||||
else:
|
||||
# Büyük dosyalar için multipart upload
|
||||
# Dosya boyutuna göre chunk boyutu ve eşzamanlılık ayarla
|
||||
if file_size > 500 * 1024 * 1024: # 500MB üstü
|
||||
chunk_size = 16 * 1024 * 1024 # 16MB chunks
|
||||
concurrency = 5
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Çok büyük dosya tespit edildi, gelişmiş ayarlar kullanılıyor</span>")
|
||||
else:
|
||||
chunk_size = 8 * 1024 * 1024 # 8MB chunks
|
||||
concurrency = 4
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Büyük dosya: standart multipart upload kullanılıyor</span>")
|
||||
|
||||
# Büyük dosyalar için gelişmiş ayarlar
|
||||
transfer_config = TransferConfig(
|
||||
multipart_threshold=1024 * 1024 * 50, # 50MB
|
||||
max_concurrency=1, # Tek thread kullan
|
||||
multipart_chunksize=1024 * 1024 * 50, # 50MB chunk
|
||||
use_threads=False
|
||||
multipart_threshold=chunk_size,
|
||||
max_concurrency=concurrency,
|
||||
multipart_chunksize=chunk_size,
|
||||
use_threads=True,
|
||||
max_io_queue=10 # I/O sırası boyutunu sınırla
|
||||
)
|
||||
|
||||
# Büyük dosyalar için ikinci bir kontrol - chunk boyutları dosya boyutuna oranla çok küçükse ayarla
|
||||
if file_size > 1024 * 1024 * 1024: # 1GB üstü
|
||||
# 10.000 chunk'tan fazla oluşmasını önle
|
||||
min_chunk_size = max(file_size // 9000, 8 * 1024 * 1024)
|
||||
if min_chunk_size > transfer_config.multipart_chunksize:
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Chunk boyutu otomatik ayarlandı: {min_chunk_size/(1024*1024):.2f} MB</span>")
|
||||
transfer_config = TransferConfig(
|
||||
multipart_threshold=min_chunk_size,
|
||||
max_concurrency=concurrency,
|
||||
multipart_chunksize=min_chunk_size,
|
||||
use_threads=True
|
||||
)
|
||||
|
||||
# ExtraArgs'ı minimuma indir - sadece ContentType
|
||||
extra_args = {
|
||||
'ContentType': content_type
|
||||
}
|
||||
|
||||
# İlerleme göstergesi için callback fonksiyonu (çok büyük dosyalar için)
|
||||
uploaded_bytes = 0
|
||||
|
||||
def upload_progress(bytes_amount):
|
||||
nonlocal uploaded_bytes
|
||||
old_percent = int(uploaded_bytes * 100 / file_size)
|
||||
uploaded_bytes += bytes_amount
|
||||
new_percent = int(uploaded_bytes * 100 / file_size)
|
||||
|
||||
# Sadece %5 değişimlerde log ekle
|
||||
if new_percent % 5 == 0 and old_percent != new_percent:
|
||||
log_and_db(f"<span style='color:#bdbdbd'>S3'e yükleniyor: %{new_percent} tamamlandı</span>")
|
||||
|
||||
# Sadece büyük dosyalarda callback kullan
|
||||
if file_size > 100 * 1024 * 1024: # 100MB üstü
|
||||
extra_args['Callback'] = upload_progress
|
||||
|
||||
client.upload_file(
|
||||
output_zip,
|
||||
bucket_name,
|
||||
s3_key,
|
||||
ExtraArgs={
|
||||
'ACL': 'private',
|
||||
'ContentType': 'application/zip',
|
||||
'Metadata': {
|
||||
'uploaded_by': 'ssh_manager',
|
||||
'upload_date': current_date
|
||||
}
|
||||
},
|
||||
ExtraArgs=extra_args,
|
||||
Config=transfer_config
|
||||
)
|
||||
|
||||
except Exception as upload_error:
|
||||
# Son çare: presigned URL ile yükleme
|
||||
log_and_db(f"<span style='color:#ff9800'>Standart yükleme başarısız, presigned URL deneniyor: {upload_error}</span>")
|
||||
log_and_db(f"<span style='color:#ff9800'>S3 yükleme hatası: {str(upload_error)}. Alternatif yöntem deneniyor...</span>")
|
||||
|
||||
try:
|
||||
presigned_url = client.generate_presigned_url(
|
||||
'put_object',
|
||||
Params={'Bucket': bucket_name, 'Key': s3_key},
|
||||
ExpiresIn=3600
|
||||
# S3Transfer ile daha basit yükleme dene
|
||||
log_and_db(f"<span style='color:#bdbdbd'>S3Transfer ile yükleme deneniyor...</span>")
|
||||
|
||||
# Tamamen farklı bir yöntem dene - S3Transfer
|
||||
from boto3.s3.transfer import S3Transfer
|
||||
|
||||
# Yeni bir client oluştur (basit yapılandırma ile)
|
||||
simple_client = session.client('s3',
|
||||
region_name=region_name,
|
||||
endpoint_url=endpoint_url,
|
||||
aws_access_key_id=config['access_key'],
|
||||
aws_secret_access_key=config['secret_key'],
|
||||
use_ssl=config['use_https'],
|
||||
verify=False
|
||||
)
|
||||
|
||||
import requests
|
||||
with open(output_zip, 'rb') as file_data:
|
||||
headers = {'Content-Type': 'application/zip'}
|
||||
response = requests.put(presigned_url, data=file_data, headers=headers)
|
||||
transfer = S3Transfer(simple_client)
|
||||
transfer.upload_file(
|
||||
output_zip,
|
||||
bucket_name,
|
||||
s3_key
|
||||
)
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>S3Transfer kullanılarak başarıyla yüklendi</span>")
|
||||
|
||||
except Exception as transfer_error:
|
||||
log_and_db(f"<span style='color:#ff9800'>S3Transfer başarısız: {str(transfer_error)}. Son yöntem deneniyor...</span>")
|
||||
|
||||
try:
|
||||
# Son çare: Presigned URL ile dene
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Son çare: Presigned URL ile yükleme deneniyor</span>")
|
||||
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"Presigned URL yükleme hatası: {response.status_code} - {response.text}")
|
||||
# Presigned URL oluştur (minimum parametrelerle)
|
||||
presigned_url = client.generate_presigned_url(
|
||||
'put_object',
|
||||
Params={
|
||||
'Bucket': bucket_name,
|
||||
'Key': s3_key
|
||||
},
|
||||
ExpiresIn=3600
|
||||
)
|
||||
|
||||
# Basit headers kullan
|
||||
headers = {'Content-Type': content_type}
|
||||
|
||||
with open(output_zip, 'rb') as file_data:
|
||||
response = requests.put(
|
||||
presigned_url,
|
||||
data=file_data,
|
||||
headers=headers,
|
||||
verify=False
|
||||
)
|
||||
|
||||
except Exception as presigned_error:
|
||||
raise Exception(f"Tüm yükleme yöntemleri başarısız: {presigned_error}")
|
||||
if response.status_code not in [200, 201]:
|
||||
raise Exception(f"HTTP hatası: {response.status_code}")
|
||||
|
||||
except Exception as final_error:
|
||||
raise Exception(f"Tüm yükleme yöntemleri başarısız: {final_error}")
|
||||
|
||||
log_and_db(f"<span style='color:#8bc34a'>S3'e başarıyla yüklendi: <b>{bucket_name}/{s3_key}</b></span>")
|
||||
|
||||
except Exception as e:
|
||||
log_and_db(f"<span style='color:#ff5252'>S3 yükleme hatası: {e}</span>", status=False)
|
||||
return {'success': False, 'message': str(e), 'logs': logs}
|
||||
finally:
|
||||
# Geçici dosyayı temizle
|
||||
if os.path.exists(output_zip):
|
||||
os.remove(output_zip)
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Geçici zip dosyası silindi: <b>{output_zip}</b></span>")
|
||||
return {'success': True, 'message': 'Yedekleme tamamlandı', 'logs': logs}
|
||||
log_and_db(f"<span style='color:#bdbdbd'>Geçici arşiv dosyası silindi: <b>{output_zip}</b></span>")
|
||||
|
||||
# SSH bağlantısını kapat
|
||||
try:
|
||||
ssh_manager.close()
|
||||
except:
|
||||
pass
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'message': 'Yedekleme tamamlandı',
|
||||
'logs': logs,
|
||||
'file_size': file_size, # Dosya boyutunu sonuca ekle
|
||||
'file_path': s3_key if 's3_key' in locals() else os.path.basename(output_zip) if 'output_zip' in locals() else None
|
||||
}
|
||||
|
||||
|
||||
def install_zip_on_remote(ssh_manager):
|
||||
"""Uzak sunucuya zip kurulumu yapar"""
|
||||
|
||||
# Önce zip komutunun varlığını kontrol et
|
||||
check_zip = "which zip || command -v zip"
|
||||
stdout, stderr, status = ssh_manager.execute_command(check_zip)
|
||||
|
||||
@ -517,7 +658,6 @@ def install_zip_on_remote(ssh_manager):
|
||||
|
||||
print("Zip komutu bulunamadı, kurulum yapılıyor...")
|
||||
|
||||
# İşletim sistemi kontrolü
|
||||
os_check = "cat /etc/os-release 2>/dev/null || uname -a"
|
||||
stdout, stderr, status = ssh_manager.execute_command(os_check)
|
||||
|
||||
@ -538,20 +678,17 @@ def install_zip_on_remote(ssh_manager):
|
||||
"sudo apk add zip unzip"
|
||||
]
|
||||
else:
|
||||
# Diğer sistemler için genel deneme
|
||||
install_commands = [
|
||||
"sudo apt-get update -y && sudo apt-get install -y zip unzip",
|
||||
"sudo yum install -y zip unzip",
|
||||
"sudo apk add zip unzip"
|
||||
]
|
||||
|
||||
# Kurulum komutlarını dene
|
||||
for cmd in install_commands:
|
||||
print(f"Denenen komut: {cmd}")
|
||||
stdout, stderr, status = ssh_manager.execute_command(cmd)
|
||||
|
||||
if status:
|
||||
# Kurulum sonrası zip kontrolü
|
||||
stdout_check, stderr_check, status_check = ssh_manager.execute_command("which zip")
|
||||
if status_check and stdout_check.strip():
|
||||
print(f"Zip başarıyla kuruldu: {stdout_check.strip()}")
|
||||
@ -566,30 +703,39 @@ def install_zip_on_remote(ssh_manager):
|
||||
def create_tar_backup(ssh_manager, source_dir, tar_name, excluded_folders=[], excluded_extensions=[]):
|
||||
"""SSH üzerinden tar kullanarak yedek oluşturur (zip alternatifi)"""
|
||||
|
||||
# Uzak sunucuda geçici tar dosyası yolu
|
||||
remote_tar_path = f"/tmp/{tar_name}"
|
||||
|
||||
# Kaynak dizinin varlığını kontrol et
|
||||
check_dir_command = f"test -d '{source_dir}' && echo 'exists' || echo 'not_exists'"
|
||||
stdout, stderr, status = ssh_manager.execute_command(check_dir_command)
|
||||
|
||||
if not status or stdout.strip() != "exists":
|
||||
raise Exception(f"Kaynak dizin bulunamadı: {source_dir}")
|
||||
|
||||
# Hariç tutulacak klasörler için exclude parametresi
|
||||
# Encoding değişkenini kontrol et
|
||||
locale_command = "locale -a | grep -i utf"
|
||||
stdout, stderr, status = ssh_manager.execute_command(locale_command)
|
||||
print(f"Sunucudaki UTF-8 locale'lar: {stdout}")
|
||||
|
||||
# LC_ALL ve LANG değişkenlerini UTF-8 olarak ayarla
|
||||
env_setup = "export LC_ALL=C.UTF-8 2>/dev/null || export LC_ALL=en_US.UTF-8 2>/dev/null || export LC_CTYPE=UTF-8; export LANG=C.UTF-8 2>/dev/null || export LANG=en_US.UTF-8;"
|
||||
|
||||
base_path = os.path.dirname(source_dir)
|
||||
folder_to_tar = os.path.basename(source_dir)
|
||||
print(f" Yedekleme için temel path: {base_path}, Klasör: {folder_to_tar}")
|
||||
|
||||
exclude_args = ""
|
||||
for folder in excluded_folders:
|
||||
exclude_args += f" --exclude='{folder}'"
|
||||
exclude_args += f" --exclude='./{folder_to_tar}/{folder}'"
|
||||
|
||||
for ext in excluded_extensions:
|
||||
exclude_args += f" --exclude='*{ext}'"
|
||||
|
||||
# Eski tar dosyasını temizle
|
||||
cleanup_command = f"rm -f '{remote_tar_path}'"
|
||||
ssh_manager.execute_command(cleanup_command)
|
||||
|
||||
# Tar komutunu oluştur (gzip ile sıkıştır)
|
||||
tar_command = f"cd '{source_dir}' && tar -czf '{remote_tar_path}' {exclude_args} . 2>/dev/null"
|
||||
# UTF-8 desteği için locale değişkenlerini ayarla ve karakter kodlamasını doğru yönet
|
||||
# --owner=0 --group=0 kullanıcı ve grup bilgilerini sıfırlar (Unicode karakterleri içermez)
|
||||
tar_command = f"{env_setup} tar --owner=0 --group=0 -czvf '{remote_tar_path}' -C '{base_path}' {exclude_args} '{folder_to_tar}'"
|
||||
|
||||
print(f"Çalıştırılan tar komutu: {tar_command}")
|
||||
|
||||
@ -598,7 +744,10 @@ def create_tar_backup(ssh_manager, source_dir, tar_name, excluded_folders=[], ex
|
||||
|
||||
print(f"Tar komutu sonucu - Status: {status}, Stdout: {stdout}, Stderr: {stderr}")
|
||||
|
||||
# Tar dosyasının varlığını kontrol et
|
||||
if not status:
|
||||
if "error" in stderr.lower() or "cannot" in stderr.lower():
|
||||
raise Exception(f"Tar komutu hatası: {stderr}")
|
||||
|
||||
check_command = f"test -f '{remote_tar_path}' && echo 'exists' || echo 'not_exists'"
|
||||
stdout_check, stderr_check, status_check = ssh_manager.execute_command(check_command)
|
||||
|
||||
@ -606,7 +755,6 @@ def create_tar_backup(ssh_manager, source_dir, tar_name, excluded_folders=[], ex
|
||||
error_details = f"Status: {status}, Stdout: {stdout}, Stderr: {stderr}"
|
||||
raise Exception(f"Tar dosyası oluşturulamadı. Detaylar: {error_details}")
|
||||
|
||||
# Dosya boyutunu al
|
||||
size_command = f"stat -c%s '{remote_tar_path}' 2>/dev/null || stat -f%z '{remote_tar_path}' 2>/dev/null || wc -c < '{remote_tar_path}'"
|
||||
stdout_size, stderr_size, status_size = ssh_manager.execute_command(size_command)
|
||||
|
||||
@ -618,9 +766,6 @@ def create_tar_backup(ssh_manager, source_dir, tar_name, excluded_folders=[], ex
|
||||
return remote_tar_path, file_size
|
||||
|
||||
except Exception as e:
|
||||
# Hata durumunda oluşmuş olabilecek tar dosyasını temizle
|
||||
cleanup_command = f"rm -f '{remote_tar_path}'"
|
||||
ssh_manager.execute_command(cleanup_command)
|
||||
raise e
|
||||
|
||||
|
||||
raise e
|
||||
Reference in New Issue
Block a user