Merger: automatically add new hosts to the known_hosts file
To improve the experience for new users, have the mergers automatically add new ssh hosts to their known hosts files. They will still validate existing entries, so a paranoid sysadmin can still pre-populate the file to avoid trojan attacks on the initial connection. New users in the typical case of a secure internal network will not need to manually add host keys to start Zuul. This matches the behavior of the scheduler with its stream-events connection to Gerrit. Change-Id: Ib416bbb2ffcfedd5d114709af3931e154a1a92ac
This commit is contained in:
parent
4c5caf78a2
commit
56ec35538a
|
@ -42,7 +42,7 @@ services:
|
|||
- mysql
|
||||
environment:
|
||||
no_proxy: "${no_proxy},gerrit"
|
||||
command: "sh -c 'ansible-playbook /var/playbooks/scheduler.yaml; zuul-scheduler -d'"
|
||||
command: "sh -c 'ansible-playbook /var/playbooks/wait-to-start.yaml; zuul-scheduler -d'"
|
||||
image: zuul/zuul-scheduler
|
||||
volumes:
|
||||
- "./etc_zuul/:/etc/zuul/:z"
|
||||
|
@ -63,7 +63,7 @@ services:
|
|||
privileged: true
|
||||
environment:
|
||||
no_proxy: "${no_proxy},gerrit"
|
||||
command: "sh -c 'ansible-playbook /var/playbooks/executor.yaml; zuul-executor -d'"
|
||||
command: "zuul-executor -d"
|
||||
depends_on:
|
||||
- scheduler
|
||||
image: zuul/zuul-executor
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# Until https://review.openstack.org/608453 merges, we need to add
|
||||
# Gerrit's SSH host keys to the known hosts_file before starting.
|
||||
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
tasks:
|
||||
- name: Wait for gerrit to start
|
||||
wait_for:
|
||||
host: gerrit
|
||||
port: 29418
|
||||
- name: Ensure SSH directory exists
|
||||
file:
|
||||
state: directory
|
||||
path: /root/.ssh
|
||||
- name: Fetch SSH host keys from Gerrit
|
||||
shell: ssh-keyscan -p 29418 gerrit > /root/.ssh/known_hosts
|
|
@ -1,5 +1,5 @@
|
|||
# The Zuul scheduler needs to be able to connect to the remote systems
|
||||
# in order to start.
|
||||
# Zuul needs to be able to connect to the remote systems in order to
|
||||
# start.
|
||||
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
|
@ -14,7 +14,7 @@
|
|||
# under the License.
|
||||
|
||||
from contextlib import contextmanager
|
||||
from urllib.parse import urlsplit, urlunsplit
|
||||
from urllib.parse import urlsplit, urlunsplit, urlparse
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
|
@ -23,6 +23,7 @@ import time
|
|||
|
||||
import git
|
||||
import gitdb
|
||||
import paramiko
|
||||
|
||||
import zuul.model
|
||||
|
||||
|
@ -82,6 +83,7 @@ class Repo(object):
|
|||
'GIT_HTTP_LOW_SPEED_TIME': speed_time,
|
||||
}
|
||||
self.git_timeout = git_timeout
|
||||
self.sshkey = sshkey
|
||||
if sshkey:
|
||||
self.env['GIT_SSH_COMMAND'] = 'ssh -i %s' % (sshkey,)
|
||||
|
||||
|
@ -93,6 +95,10 @@ class Repo(object):
|
|||
self._initialized = False
|
||||
self.retry_attempts = retry_attempts
|
||||
self.retry_interval = retry_interval
|
||||
try:
|
||||
self._setup_known_hosts()
|
||||
except Exception:
|
||||
self.log.exception("Unable to set up known_hosts for %s" % remote)
|
||||
try:
|
||||
self._ensure_cloned()
|
||||
self._git_set_remote_url(
|
||||
|
@ -100,6 +106,36 @@ class Repo(object):
|
|||
except Exception:
|
||||
self.log.exception("Unable to initialize repo for %s" % remote)
|
||||
|
||||
def _setup_known_hosts(self):
|
||||
url = urlparse(self.remote_url)
|
||||
if 'ssh' not in url.scheme:
|
||||
return
|
||||
|
||||
port = url.port or 22
|
||||
username = url.username or self.username
|
||||
|
||||
path = os.path.expanduser('~/.ssh')
|
||||
os.makedirs(path)
|
||||
path = os.path.expanduser('~/.ssh/known_hosts')
|
||||
if not os.path.exists(path):
|
||||
with open(path, 'w'):
|
||||
pass
|
||||
|
||||
client = paramiko.SSHClient()
|
||||
client.load_system_host_keys()
|
||||
client.load_host_keys(path)
|
||||
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
|
||||
try:
|
||||
client.connect(url.hostname,
|
||||
username=username,
|
||||
port=port,
|
||||
key_filename=self.sshkey)
|
||||
finally:
|
||||
# If we don't close on exceptions to connect we can leak the
|
||||
# connection and DoS Gerrit.
|
||||
client.close()
|
||||
|
||||
def _ensure_cloned(self):
|
||||
repo_is_cloned = os.path.exists(os.path.join(self.local_path, '.git'))
|
||||
if self._initialized and repo_is_cloned:
|
||||
|
|
Loading…
Reference in New Issue