Resolvi meu problema usando as etapas descritas em this S.O. responder . Basicamente, faça:
ssh-keygen -t rsa -P ""
cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
ssh localhost
então
start-dfs.sh
não pedirá senhas.
Por isso, estou executando o Hadoop no modo pseudo-distribuído no meu laptop para aprender sobre essas coisas.
Estou configurando as coisas como explicado no manual .
Eu posso começar o hadoop, sem problemas, mas o processo de lançamento é inconveniente. Veja, para lançar a coisa, um faz:
start-dfs.sh
Em seguida, um é solicitado a digitar a senha 3 vezes (no meu caso, todas as três são iguais):
Starting namenodes on [localhost]
me@localhost's password:
localhost: starting namenode, logging to /home/me/hadoop-2.7.3/logs/hadoop-me-namenode-me-HP-ENVY-15-Notebook-PC.out
me@localhost's password:
localhost: starting datanode, logging to /home/me/hadoop-2.7.3/logs/hadoop-me-datanode-me-HP-ENVY-15-Notebook-PC.out
Starting secondary namenodes [0.0.0.0]
[email protected]'s password:
0.0.0.0: starting secondarynamenode, logging to /home/me/hadoop-2.7.3/logs/hadoop-me-secondarynamenode-me-HP-ENVY-15-Notebook-PC.out
(e mesmo quando se faz stop-dfs.sh
).
Isso é uma dor. Existe uma maneira de o ubuntu lembrar essa senha para que não seja necessário digitá-la?
Resolvi meu problema usando as etapas descritas em this S.O. responder . Basicamente, faça:
ssh-keygen -t rsa -P ""
cat $HOME/.ssh/id_rsa.pub >> $HOME/.ssh/authorized_keys
ssh localhost
então
start-dfs.sh
não pedirá senhas.
Eu também tentaria o seguinte (se você tiver um usuário hdfs):
sudo -u hdfs start-dfs.sh service-name
Dessa forma, você digitaria a senha uma vez, mas as chamadas subsequentes devem ser armazenadas em cache.
Uma idéia é iniciar o processo em segundo plano, redirecionando seu stdout (stderr?) para um arquivo e fazer com que seu script aguarde e monitore esse arquivo em um loop. Sempre que o processo imprime a solicitação de senha, o script alimenta a senha no processo por meio de seu stdin.
Conseguir isso é realmente complicado. Você pode usar dois scripts, um para monitorar a saída e alimentar as senhas, e outro para iniciá-los primeiro, aplicando os redirecionamentos necessários.
Portanto, o script de inicialização é:
#!/bin/bash
TEMP_FILE=/tmp/hapboon.stdout
start-dfs.sh <(./feed-passwords.py "$TEMP_FILE") > "$TEMP_FILE"
Por alguma razão, vou usar o Python para o outro:
#!/usr/bin/python3
PASSWORD="""TYPE_YOUR_PASSWORD_HERE"""
from sys import argv
temp_file = argv[1] # Raises exception if argument is missing
counter = 0
maximum = 3
previous_length = 0
while True:
with open(temp_file) as f:
output = f.read()
if len(output) == previous_length:
continue
previous_length = len(output)
last_line = output.strip().split('\n')[-1]
if last_line.endswith(' password:'):
print(PASSWORD) # Our stdout goes to 'start-dfs.sh'
counter += 1
if counter == maximum:
break
Eu não testei nada disso. Uma suposição de que esta abordagem se baseia é que aquele que recebe a senha através de sua stdin é start-dfs.sh
em si, que tem uma boa possibilidade de ser falso. Iniciar scripts frequentemente apenas invocam outros processos, então a senha provavelmente precisa ser enviada para o stdin dos outros processos.
Você pode ter que mexer com o script start-dfs.sh
e redirecionar o stdin dos processos que receberão a senha. Isso também implica que nosso script feed-passwords.py
deve imprimir as senhas no arquivo apropriado a cada vez, o que provavelmente significa que a arquitetura de toda a abordagem mudaria.
Além disso, enquanto ainda não estamos lá, mais uma coisa sobre esse script é inflexível; ele só funciona com um número predefinido de senhas (definido pela variável maximum
). Pode ser desejável modificá-lo de tal forma que ele continue monitorando os prompts de senha até que um certo tempo limite (digamos, 15 segundos) tenha passado, acomodando assim qualquer número de prompts de senha sem a necessidade de alterar o número toda vez. (Eu posso te ajudar com isso, caso seja necessário.)
Outra observação: se você não quiser armazenar sua senha, basta substituir a linha PASSWORD=...
por: PASSWORD=input("Type your password: ")
. Isso fará com que você insira sua senha apenas uma vez sempre que iniciar o script e não armazenará sua senha em nenhum lugar.