Koipse
@Koipse

Proxmox | Python | Paramiko | Вхождение в контейнер?

Приветствую!

Суть вопроса: Есть сервер, что работает на proxmox. Есть контейнера, что там крутятся. Может ли кто-то, пожалуйста, подсказать способ написания метода для "внедрения" в контейнер через сервер, на который мы ломимся через ssh, используя Paramiko?

Что у нас есть?

1. Класс SSH с инициализацией
2. Метод, что реализует коннект к серверу по уже известным параметрам.

def connect_to_server(self):
        try:
            self.client.connect(hostname=self.connection, username=self.login, password=self.password, port=22,
                                auth_timeout=True, timeout=5)
        except ssh.ssh_exception.AuthenticationException:
            print('Ошибка при логировании на сервер')
            self.close_connection()
        except socket.error:
            print("Сервер недоступен!")
            self.close_connection()


Есть простой метод, благодаря которому я могу увидеть все контейнера внутри. Обыкновенный вывод.

def show_containers(self):
        if not self.closeSSH:
            stdin, stdout, stderr = self.client.exec_command("pct list", get_pty=True)
            stdin.write('')
            stdin.flush()
            data = stdout.read() + stderr.read()
            print(data.decode())
        else:
            return "No connection to server"


Как бы я не пытался зайти на какой-либо контейнер, при проверке «правильности» захода, я смотрел хостнейм контейнера, пробуя комманду .exec_command("cat /etc/hostname, get_pty=True), но все время вывод был один – "mainserver", когда мне нужен был другой вывод, например: «slavecontainer»

Я пробовал войти в контейнер, прописывая подобный код, что использовал на вывод списка контейнеров, однако ничего дельного не получается:

def enter_to_server(self):
        if not self.closeSSH:
            self.client.exec_command("pct enter 81103", get_pty=True) [Заходим внутрь контейнера]
            stdin, stdout, stderr = self.client.exec_command("cat /etc/hostname", get_pty=True) [Пытаемся узнать имя контейнера]
            stdin.write('')
            stdin.flush()
            data = stdout.read() + stderr.read()
            print(data.decode()) [Выводит "mainserver"]
        else:
            return "No connection to server"


Я подозреваю, что где-то нужно, могу неправильно выразится, перехватить момент захода в контейнер, сродни еще одной tty, но складывается впечатление, что команда либо вовсе не исполняется, либо запрос идет, но мы сами "остались" на прежней точке.

Ну и глупая реализация (т.к. просто выводить нечего):

def enter_to_server(self):
        if not self.closeSSH:
            stdin, stdout, stderr = self.client.exec_command("pct enter 81103", get_pty=True)
            stdin.write('')
            stdin.flush()
            data = stdout.read() + stderr.read()
            print(data.decode())
        else:
            return "No connection to server"


Разумеется, что при исполнении:
stdin, stdout, stderr = self.client.exec_command("pct enter 81103", get_pty=True)


Мы просто зависнем, а при добавлении аргумента с таймаутом упремся в ошибки paramiko.buffered_pipe.PipeTimeout и socket.timeout.

Оттого возникает вопрос: возможно, момент "перехода" от сервера к контейнеру можно перехватить для корректного исполнения команды и последующего вывода? Субпроцессы, например?

Благодарю за внимание.
  • Вопрос задан
  • 234 просмотра
Пригласить эксперта
Ответы на вопрос 1
@AUser0
Чем больше знаю, тем лучше понимаю, как мало знаю.
Я не спец в python, но кое-что подсказать могу:
stdin, stdout, stderr = self.client.exec_command("echo 'pwd ; exit' | pct enter 81103", get_pty=True)


Ну и объяснение: IMHO, exec_command выполняет команду и ждет её завершения, что-бы вернуть результат. А у вас там interactive shell, которому никто команд не даёт, тем более команд на закрытие самого shell-а. Или делайте invoke_shell и send, или вот таким способом.

P.S. пример для подражания
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы