2

I have an array of data for the server, I need to run a sequence of commands on them

after the command seid keys add WALLET_NAME, I need to enter the password, how can I do this?

import paramiko
import time

def send_command(
        ip,
        username,
        password,
        monikername,
        walletname,
        nodepass,
        commands,
        short_pause = 1,
        long_pause = 5,
):
    cl = paramiko.SSHClient()
    cl.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    cl.connect(
        hostname=ip,
        username=username,
        password=password,
        look_for_keys=False,
        allow_agent=False,
    )
    with cl.invoke_shell() as ssh:
        for command in commands:
            ssh.send(f"{command}\n")
            ssh.settimeout(5)


if __name__ == "__main__":
    commands = [
        "sudo apt update && sudo apt upgrade -y",
        'ver="1.18.1" && \
        wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz" && \
        sudo rm -rf /usr/local/go && \
        sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz" && \
        rm "go$ver.linux-amd64.tar.gz" && \
        echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile && \
        source $HOME/.bash_profile && \
        go version',
        "git clone https://github.com/sei-protocol/sei-chain.git && cd sei-chain",
        "git checkout 1.0.6beta",
        "make install",
        "seid version --long | head",
        "seid init MONIKERNAME --chain-id atlantic-1",
        "seid keys add WALLET_NAME",
        "seid add-genesis-account WALLET_NAME 100000000usei",
        'seid gentx WALLET_NAME 100000000usei \
        --chain-id atlantic-1 \
        --commission-rate=0.1 \
        --commission-max-rate=0.2 \
        --commission-max-change-rate=0.1 \
        --pubkey $(seid tendermint show-validator) \
        --moniker "MONIKERNAME"',
        "cat ~/.sei/config/gentx/gentx-*"
    ]
    result = send_command(ip, username, password, monikername, walletname, nodepass,commands)
    print(result)

For an array with server data, I execute a loop like this

for key in data:
    ip = key['ip']
    username = key['username']
    password = key['pass']
    monikername = key['monikername']
    walletname = key['walletname']
    nodepass = key['nodepass']
    result = send_command(ip, username, password, monikername, walletname, 
    nodepass, commands)
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
TokyoDead
  • 23
  • 3
  • Paramiko can be difficult to work with, but there's nothing better to use in Python. Here is [an example](https://qxf2.com/blog/handling-set-new-password-prompt-with-paramiko/) of how somebody else handled this sort of problem. – hostingutilities.com Jul 09 '22 at 23:17

1 Answers1

0

You are using a "shell" channel to execute the commands.

The shell is a blackbox with an input and output. So you are not "inserting a password or some other string into a running script". You are simply providing a continuous stream of input into the shell. From your API point of view, it hardly matters if the input is a command or an input to a command. So the command input can easily be just another entry in your "command list".

        "seid keys add WALLET_NAME",
        "password",

Though note that using the "shell" channel to automate command execution is a wrong approach. See What is the difference between exec_command and send with invoke_shell() on Paramiko?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992