서버를 관리할 일이 있었는데 Ansible을 쓰는 것이 좋은 방법이지만, 나는 간단한 기능을 원했고 마음대로 커스터마이즈 하고 싶어서 python으로 코드를 만들었다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import paramiko | |
import re | |
import time | |
# reference sites | |
# * https://stackoverflow.com/questions/1911690/nested-ssh-session-with-paramiko | |
# * https://stackoverflow.com/questions/53707630/paramiko-how-to-detect-if-command-executed-using-invoke-shell-has-finished | |
# use paramiko library | |
class SSHConnect: | |
def __init__(self): | |
self.client = paramiko.SSHClient() | |
self.transport = None | |
def connectAndOpen(self, host, port, username, password): | |
self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy) | |
self.client.connect( hostname = host, port = port, username = username, password = password, allow_agent = True ) | |
print ("Connected to %s" % host) | |
self.transport = self.client.get_transport() | |
self.password = password | |
return | |
def runCommand(self, commandText): | |
print("> %s" % commandText) | |
self.session = self.transport.open_session() | |
self.session.set_combine_stderr(True) | |
self.session.get_pty() | |
self.session.setblocking(1) | |
self.session.exec_command(commandText) | |
loop = 1 | |
while loop > 0: | |
loop = loop – 1 | |
while self.session.exit_status_ready()==False: | |
stdout = self.session.recv(1024).decode("utf-8") | |
# When requesting password input, put the stored password. | |
if re.search('[Pp]assword', stdout): | |
self.session.send(self.password+'\n') | |
loop = loop + 1 | |
else: | |
print(stdout, end='') | |
self.session.close() | |
return | |
def close(self): | |
self.transport.close() | |
self.transport = None | |
self.client.close() | |
self.client = None | |
Host = '127.0.0.1' | |
Port = 22 | |
ID = '' | |
Password = '' | |
con = SSHConnect() | |
con.connectAndOpen(Host, Port, ID, Password) | |
print("Start") | |
con.runCommand("df -h") | |
time.sleep(1) | |
con.runCommand("sudo apt update && sudo apt upgrade -y") | |
print("End") | |
con.close() |
위 코드는 패스워드를 사용해서 접속하고 sudo 등의 커맨드에서 password 를 자동으로 입력해주는 샘플 코드다. 실제로 쓰는 코드는 ssh키도 사용할 수 있고, 서버 설정 파일을 cryptography 라이브러리를 사용하여 암호화 시켜서 쓴다.
그리고,실행 중에 화면 입력을 필요로 할 때에는 무한 대기 상태에 빠져버리는 문제가 있다.