Generate and deploy real WG/AWG configs to VPS over SSH
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -108,6 +108,43 @@ class SSHManager:
|
||||
full = f"sudo {clean}"
|
||||
return self.run_command(full, timeout=timeout)
|
||||
|
||||
def upload_file(self, content: str, remote_path: str) -> None:
|
||||
if not self.client:
|
||||
raise ConnectionError("Not connected to server")
|
||||
content = content.replace("\r\n", "\n")
|
||||
sftp = self.client.open_sftp()
|
||||
try:
|
||||
with sftp.file(remote_path, "w") as f:
|
||||
f.write(content)
|
||||
finally:
|
||||
sftp.close()
|
||||
|
||||
def upload_file_sudo(self, content: str, remote_path: str) -> None:
|
||||
import hashlib
|
||||
|
||||
tmp = f"/tmp/_vpnpanel_{hashlib.md5(remote_path.encode()).hexdigest()[:8]}"
|
||||
self.upload_file(content, tmp)
|
||||
self.run_sudo_command(f"mv {tmp} {remote_path}")
|
||||
self.run_sudo_command(f"chmod 644 {remote_path}")
|
||||
|
||||
def run_sudo_script(self, script: str, timeout: int = 180) -> tuple[str, str, int]:
|
||||
import hashlib
|
||||
|
||||
script = script.replace("\r\n", "\n")
|
||||
tmp = f"/tmp/_vpnpanel_script_{hashlib.md5(script.encode()).hexdigest()[:8]}.sh"
|
||||
self.upload_file(script, tmp)
|
||||
if self._is_root:
|
||||
out = self.run_command(f"bash {tmp}; rm -f {tmp}", timeout=timeout)
|
||||
elif self.password:
|
||||
escaped = self.password.replace("'", "'\\''")
|
||||
out = self.run_command(
|
||||
f"echo '{escaped}' | sudo -S -p '' bash {tmp}; rm -f {tmp}",
|
||||
timeout=timeout,
|
||||
)
|
||||
else:
|
||||
out = self.run_command(f"sudo bash {tmp}; rm -f {tmp}", timeout=timeout)
|
||||
return out
|
||||
|
||||
def test_connection(self) -> str:
|
||||
out, err, code = self.run_command(
|
||||
"uname -sr && cat /etc/os-release 2>/dev/null | head -2"
|
||||
|
||||
Reference in New Issue
Block a user