rpm-ostree/tests/library/qemu_provision.py
Jonathan Lebon d11be14ae1 tests: run parts of the vmcheck testsuite
Run the basic and layering-basic vmcheck tests on qcow2 Atomic Host
images. It's full of hacks for now; I'd like to confirm first that there
aren't any oversights that would prevent the pipeline from running it.

Once we get it going, we can work on cleaning up and upstreaming the
hacks to standard-test-roles, and run all the vmcheck tests.
2017-08-15 14:44:18 -04:00

147 lines
5.4 KiB
Python

#!/usr/bin/env python
# XXX: we should move as much of these mods to standard-test-roles
import os
import shutil
import signal
import subprocess
import sys
import tempfile
# HACK: Ansible requires this exact string to be here
from ansible.module_utils.basic import *
#
# Test this module like this
#
# echo '{ "ANSIBLE_MODULE_ARGS": { "subjects": "cloud.qcow2" } }' \
# | python tests/library/qemu-playbook.py
#
WANT_JSON = True
IDENTITY = """
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA1DrTSXQRF8isQQfPfK3U+eFC4zBrjur+Iy15kbHUYUeSHf5S
jXPYbHYqD1lHj4GJajC9okle9rykKFYZMmJKXLI6987wZ8vfucXo9/kwS6BDAJto
ZpZSj5sWCQ1PI0Ce8CbkazlTp5NIkjRfhXGP8mkNKMEhdNjaYceO49ilnNCIxhpb
eH5dH5hybmQQNmnzf+CGCCLBFmc4g3sFbWhI1ldyJzES5ZX3ahjJZYRUfnndoUM/
TzdkHGqZhL1EeFAsv5iV65HuYbchch4vBAn8jDMmHh8G1ixUCL3uAlosfarZLLyo
3HrZ8U/llq7rXa93PXHyI/3NL/2YP3OMxE8baQIDAQABAoIBAQCxuOUwkKqzsQ9W
kdTWArfj3RhnKigYEX9qM+2m7TT9lbKtvUiiPc2R3k4QdmIvsXlCXLigyzJkCsqp
IJiPEbJV98bbuAan1Rlv92TFK36fBgC15G5D4kQXD/ce828/BSFT2C3WALamEPdn
v8Xx+Ixjokcrxrdeoy4VTcjB0q21J4C2wKP1wEPeMJnuTcySiWQBdAECCbeZ4Vsj
cmRdcvL6z8fedRPtDW7oec+IPkYoyXPktVt8WsQPYkwEVN4hZVBneJPCcuhikYkp
T3WGmPV0MxhUvCZ6hSG8D2mscZXRq3itXVlKJsUWfIHaAIgGomWrPuqC23rOYCdT
5oSZmTvFAoGBAPs1FbbxDDd1fx1hisfXHFasV/sycT6ggP/eUXpBYCqVdxPQvqcA
ktplm5j04dnaQJdHZ8TPlwtL+xlWhmhFhlCFPtVpU1HzIBkp6DkSmmu0gvA/i07Z
pzo5Z+HRZFzruTQx6NjDtvWwiXVLwmZn2oiLeM9xSqPu55OpITifEWNjAoGBANhH
XwV6IvnbUWojs7uiSGsXuJOdB1YCJ+UF6xu8CqdbimaVakemVO02+cgbE6jzpUpo
krbDKOle4fIbUYHPeyB0NMidpDxTAPCGmiJz7BCS1fCxkzRgC+TICjmk5zpaD2md
HCrtzIeHNVpTE26BAjOIbo4QqOHBXk/WPen1iC3DAoGBALsD3DSj46puCMJA2ebI
2EoWaDGUbgZny2GxiwrvHL7XIx1XbHg7zxhUSLBorrNW7nsxJ6m3ugUo/bjxV4LN
L59Gc27ByMvbqmvRbRcAKIJCkrB1Pirnkr2f+xx8nLEotGqNNYIawlzKnqr6SbGf
Y2wAGWKmPyEoPLMLWLYkhfdtAoGANsFa/Tf+wuMTqZuAVXCwhOxsfnKy+MNy9jiZ
XVwuFlDGqVIKpjkmJyhT9KVmRM/qePwgqMSgBvVOnszrxcGRmpXRBzlh6yPYiQyK
2U4f5dJG97j9W7U1TaaXcCCfqdZDMKnmB7hMn8NLbqK5uLBQrltMIgt1tjIOfofv
BNx0raECgYEApAvjwDJ75otKz/mvL3rUf/SNpieODBOLHFQqJmF+4hrSOniHC5jf
f5GS5IuYtBQ1gudBYlSs9fX6T39d2avPsZjfvvSbULXi3OlzWD8sbTtvQPuCaZGI
Df9PUWMYZ3HRwwdsYovSOkT53fG6guy+vElUEDkrpZYczROZ6GUcx70=
-----END RSA PRIVATE KEY-----
"""
USER_DATA = """#cloud-config
users:
- default
- name: root
ssh_authorized_keys:
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUOtNJdBEXyKxBB898rdT54ULjMGuO6v4jLXmRsdRhR5Id/lKNc9hsdioPWUePgYlqML2iSV72vKQoVhkyYkpcsjr3zvBny9+5xej3+TBLoEMAm2hmllKPmxYJDU8jQJ7wJuRrOVOnk0iSNF+FcY/yaQ0owSF02Nphx47j2KWc0IjGGlt4fl0fmHJuZBA2afN/4IYIIsEWZziDewVtaEjWV3InMRLllfdqGMllhFR+ed2hQz9PN2QcapmEvUR4UCy/mJXrke5htyFyHi8ECfyMMyYeHwbWLFQIve4CWix9qtksvKjcetnxT+WWrutdr3c9cfIj/c0v/Zg/c4zETxtp standard-test-qcow2
ssh_pwauth: True
chpasswd:
list: |
root:foobar
expire: False
"""
INVENTORY = "localhost ansible_ssh_port=2222 ansible_ssh_host=127.0.0.3 ansible_ssh_user=root ansible_ssh_private_key_file=%s ansible_ssh_common_args='-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null'\nexecutor ansible_ssh_host=127.0.0.1 ansible_connection=local"
SSH_CONFIG = """
Host vmcheck
User root
Port 2222
HostName 127.0.0.3
IdentityFile %s
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
"""
def main(argv):
module = AnsibleModule(argument_spec = {
"subjects": { "required": True, "type": "str" },
"log": { "required": False, "type": "str" },
})
null = open(os.devnull, 'w')
directory = tempfile.mkdtemp(prefix="launch-cloud-")
privkey = os.path.join(directory, "key")
with open(privkey, 'w') as f:
f.write(IDENTITY)
os.chmod(privkey, 0600)
metadata = os.path.join(directory, "meta-data")
with open(metadata, 'w') as f:
f.write("")
userdata = os.path.join(directory, "user-data")
with open(userdata, 'w') as f:
f.write(USER_DATA)
sshconfig = os.path.join(directory, "ssh-config")
with open(sshconfig, 'w') as f:
f.write(SSH_CONFIG % privkey)
cloudinit = os.path.join(directory, "cloud-init.iso")
subprocess.check_call(["/usr/bin/genisoimage", "-input-charset", "utf-8",
"-volid", "cidata", "-joliet", "-rock", "-quiet",
"-output", cloudinit, userdata, metadata], stdout=null)
log = module.params.get("log") or os.devnull
inventory = os.path.join(directory, "inventory")
with open(inventory, 'w') as f:
f.write(INVENTORY % privkey)
pid = os.path.join(directory, "pid")
subprocess.check_call(["/usr/bin/qemu-system-x86_64", "-m", "1024", module.params["subjects"],
"-enable-kvm", "-snapshot", "-cdrom", cloudinit,
"-net", "nic,model=virtio", "-net", "user,hostfwd=tcp:127.0.0.3:2222-:22",
"-device", "isa-serial,chardev=pts2", "-chardev", "file,id=pts2,path=" + log,
"-daemonize", "-display", "none", "-pidfile", pid], stdout=null)
# wait for ssh to come up
for tries in range(0, 30):
try:
subprocess.check_call(["/usr/bin/ansible", "-i", inventory, "localhost", "-m", "ping"],
stdout=null, stderr=null)
break
except subprocess.CalledProcessError:
time.sleep(3)
else:
with open(pid, 'r') as f:
try:
os.kill(int(f.read().strip()), signal.SIGTERM)
except OSError:
pass
module.fail_json(msg="Couldn't connect to qemu host: {subjects}".format(**module.params))
return 0
module.exit_json(changed=True, statedir=directory)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))