copr-be: use resalloc-aws-wait-for-ssh from resalloc-aws

Instead of copy-pasted wait-for-ssh one in this repo.  Long term it
would be better if we moved the script into 'resalloc-server' or
'resalloc-server-helpers' (or alike).
This commit is contained in:
Pavel Raiskup 2022-11-23 11:25:39 +01:00
parent c3942af631
commit 4fd58b6c40
5 changed files with 2 additions and 176 deletions

View file

@ -1,2 +0,0 @@
Download up2date version from:
https://github.com/praiskup/wait-for-ssh

View file

@ -1,164 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2017 Pavel Raiskup
#
# This program accepts one argument IP or HOSTNAME. First try to connect to the
# HOSTNAME as 'root' user. If cloud-init scripts instruct us to use different
# user than 'root', switch to that user and check again. In the end, print the
# successful username on stdout.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from re import compile as re_compile
from time import sleep
from sys import exit
from os import devnull
from threading import Thread, Event
from argparse import ArgumentParser
from subprocess import Popen, CalledProcessError, PIPE
from pipes import quote
import logging
handler = logging.StreamHandler()
log = logging.getLogger()
log.setLevel(logging.INFO)
log.addHandler(handler)
# create console handler and set level to debug
ssh = [
'ssh',
'-o', 'StrictHostKeyChecking=no',
'-o', 'UserKnownHostsFile=/dev/null',
'-o', 'PasswordAuthentication=no',
'-o', 'ConnectTimeout=10',
]
expected_output = 'foobar'
inner_cmd = 'echo ' + expected_output
class Checker(Thread):
user = 'root'
daemon = True
user_re = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[$]?'
re_clouduser = re_compile('Please login as the user "({0})"'.format(user_re))
event = Event()
def loop(self):
cmd = ssh + [
'{0}@{1}'.format(self.user, self.args.host),
inner_cmd,
]
with open(devnull, 'w') as drop:
log.debug('executing: ' + ' '.join(cmd))
self.child = Popen(cmd, stdout=PIPE, stderr=drop)
(stdout, _) = self.child.communicate()
exp = (expected_output + '\n').encode('ascii')
if self.child.returncode == 0 and stdout == exp:
if self.args.print_user:
print(self.user)
return True
if self.args.cloud_user:
match = self.re_clouduser.search(str(stdout))
if match:
self.user = match.group(1)
log.info('cloud user switched to ' + self.user)
return False
def run(self):
while True:
if self.loop():
# Success!
break
if self.event.wait(1):
log.debug("stopping per kill event")
break
def kill(self):
self.event.set()
# Best effort kill.
try:
self.child.kill()
except:
pass
self.join()
parser = ArgumentParser(
description="Wait till the host's ssh becomes responsive.")
parser.add_argument('host', help='hostname or IP')
parser.add_argument('--timeout',
help='seconds to wait before failure, default=indefinitely',
default=None, type=float)
parser.add_argument('--check-cloud-user', action='store_true', default=False,
dest='cloud_user',
help='if cloud-init disallows "root" login, try to detect the cloud ' \
+'user and use that')
parser.add_argument('--print-user', action='store_true', default=False,
dest='print_user',
help='print the username which succeeded to connect on stdout')
parser.add_argument('--log', default=False,
dest='log_verbosity',
help='set the threshold for logging, e.g. debug, info, error, ...')
def main():
sleep_period = 1.0
args = parser.parse_args()
if args.log_verbosity:
log.setLevel(logging.getLevelName(args.log_verbosity.upper()))
def timeouted():
if args.timeout is None:
return False
log.debug("wait {0}s, remains {1}s".format(sleep_period, args.timeout))
args.timeout -= sleep_period
return args.timeout <= 0
checker = Checker()
checker.args = args
checker.start()
try:
# threading.join() is not Ctrl-C interruptable :( in python2, so we need
# this ugly infinite loop.
# https://stackoverflow.com/questions/25676835/signal-handling-in-multi-threaded-python
while True:
checker.join(sleep_period)
if not checker.is_alive():
# Success!
return 0
if timeouted():
log.error("timeout!")
checker.kill()
return 1
except KeyboardInterrupt:
log.error("interrupt by user")
checker.kill()
return 1
if __name__ == "__main__":
exit(main())

View file

@ -68,14 +68,6 @@
when:
- cloud_vars is defined and cloud_vars
- name: wait-for-ssh script
copy:
src: "{{ roles_path }}/copr/backend/files/resalloc_provision/wait-for-ssh/wait-for-ssh"
mode: 0755
dest: "{{ provision_directory }}/wait-for-ssh"
tags:
- provision_config
- name: put copr-rpmbuild configuration file into the provision subdir
template: src="{{ roles_path }}/copr/backend/templates/provision/copr-rpmbuild/main.ini.j2"
dest="{{ provision_directory }}/files/main.ini"

View file

@ -85,7 +85,7 @@ class LibvirtSpawner:
Knowing the IP address of recently started VM, wait for the SSH server
responding on that IP.
"""
script = "{{ provision_directory }}/wait-for-ssh"
script = "resalloc-aws-wait-for-ssh"
if self.call([script, '--timeout', '180', host, '--log', 'debug']):
raise Exception("waiting not successful")

View file

@ -16,7 +16,7 @@ resalloc-openstack-new \
--image "{{ copr_builder_images.osuosl.ppc64le }}" \
--flavor "$flavor" \
--name "$RESALLOC_NAME" \
--post-command "set -x ; {{ provision_directory }}/wait-for-ssh --timeout 250 --log debug \"\$RESALLOC_OS_IP\" >&2 && ansible-playbook $playbook -i \"\$RESALLOC_OS_IP,\" >&2 " \
--post-command "set -x ; resalloc-aws-wait-for-ssh --timeout 250 --log debug \"\$RESALLOC_OS_IP\" >&2 && ansible-playbook $playbook -i \"\$RESALLOC_OS_IP,\" >&2 " \
--key-pair-id copr-builder \
--nic net-id="$network" \
--print-ip