I've searched extensively on Google and stackOverflow but cannot find relevant answer. So asking here. Hope you can kindly demo how to do it.
My use case is as follows:
- User put in ip addresses in a django form field (e.g. 12.12.12.12, 13.13.13.13, 14.14.14.14)
- django take ips and ssh to those machines and execute predefined script
- if script runs successfully, then django saves the result to database
- django display each server's execution results (successful, failed)
I can achieve the above function using sync methods, but the wait time is unbearably long. Trying to use asyncio.run to improve it but tried and failed repetatively. :S Here is my code:
in views.py
def create_record(request):
record_form = RecordForm()
if request.method == 'POST':
record_form = RecordForm(request.POST)
if record_form.is_valid():
ips = record_form.cleaned_data['ip'].split(',')
start_time = time.time()
for ip in ips:
record_form = RecordForm(request.POST)
record = record_form.save(commit=False)
record.ip = ip
record = asyncio.run(run_script(record)) # this function ssh to server and execute commands
if record is correct:
record.save()
messages.success(request, ip + ' execution success')
else:
messages.error(request, ip + ' execution failed')
total = time.time() - start_time
print('total:', total)
return redirect('create_record')
context = {'record_form': record_form}
return render(request, 'record-form.html', context)
the run_script goes as:
async def run_script(record):
client = paramiko.SSHClient()
client.load_system_host_keys()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
client.connect(record.ip, username='xxx', pass)
ssh_stdin, ssh_stdout, ssh_stderr = await client.exec_command('{script.sh}') #python complains await cannot be used here
# process output
for line in ssh_stdout:
info = line.strip('\n')
except Exception as e:
print("Exception: ", e)
client.close()
record.info = info
return record