File size: 1,947 Bytes
2b64d42 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #!/usr/bin/env python3
"""Execute a command on a VPS via SSH.
Required environment variables:
WINDSURFAPI_VPS_HOST
WINDSURFAPI_VPS_USER
Authentication:
WINDSURFAPI_VPS_PASS, or WINDSURFAPI_VPS_KEY pointing at a private key file.
"""
import os
import sys
import paramiko
os.environ.setdefault('PYTHONIOENCODING', 'utf-8')
sys.stdout.reconfigure(encoding='utf-8', errors='replace')
sys.stderr.reconfigure(encoding='utf-8', errors='replace')
def _env(name, required=True):
value = os.environ.get(name, '').strip()
if required and not value:
raise SystemExit(f'Missing required environment variable: {name}')
return value
def run(cmd, timeout=600):
host = _env('WINDSURFAPI_VPS_HOST')
user = _env('WINDSURFAPI_VPS_USER')
password = _env('WINDSURFAPI_VPS_PASS', required=False)
key_path = _env('WINDSURFAPI_VPS_KEY', required=False)
if not password and not key_path:
raise SystemExit('Set WINDSURFAPI_VPS_PASS or WINDSURFAPI_VPS_KEY before running this helper')
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
connect_kwargs = {
'hostname': host,
'username': user,
'timeout': 10,
}
if key_path:
connect_kwargs['key_filename'] = key_path
else:
connect_kwargs['password'] = password
client.connect(**connect_kwargs)
try:
stdin, stdout, stderr = client.exec_command(cmd, timeout=timeout)
out = stdout.read().decode('utf-8', errors='replace')
err = stderr.read().decode('utf-8', errors='replace')
code = stdout.channel.recv_exit_status()
return out, err, code
finally:
client.close()
if __name__ == '__main__':
command = sys.argv[1] if len(sys.argv) > 1 else 'echo hello'
out, err, code = run(command)
if out:
print(out, end='')
if err:
print(err, end='', file=sys.stderr)
sys.exit(code)
|