| |
@@ -12,7 +12,6 @@
|
| |
import sys
|
| |
import tempfile
|
| |
import time
|
| |
- import traceback
|
| |
import distutils.util
|
| |
|
| |
IDENTITY = """
|
| |
@@ -49,6 +48,8 @@
|
| |
users:
|
| |
- default
|
| |
- name: root
|
| |
+ groups: sudo
|
| |
+ shell: /bin/bash
|
| |
ssh_authorized_keys:
|
| |
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUOtNJdBEXyKxBB898rdT54ULjMGuO6v4jLXmRsdRhR5Id/lKNc9hsdioPWUePgYlqML2iSV72vKQoVhkyYkpcsjr3zvBny9+5xej3+TBLoEMAm2hmllKPmxYJDU8jQJ7wJuRrOVOnk0iSNF+FcY/yaQ0owSF02Nphx47j2KWc0IjGGlt4fl0fmHJuZBA2afN/4IYIIsEWZziDewVtaEjWV3InMRLllfdqGMllhFR+ed2hQz9PN2QcapmEvUR4UCy/mJXrke5htyFyHi8ECfyMMyYeHwbWLFQIve4CWix9qtksvKjcetnxT+WWrutdr3c9cfIj/c0v/Zg/c4zETxtp standard-test-qcow2
|
| |
ssh_pwauth: True
|
| |
@@ -58,6 +59,7 @@
|
| |
expire: False
|
| |
"""
|
| |
|
| |
+
|
| |
def main(argv):
|
| |
parser = argparse.ArgumentParser(description="Inventory for a QCow2 test image")
|
| |
parser.add_argument("--list", action="store_true", help="Verbose output")
|
| |
@@ -77,39 +79,48 @@
|
| |
|
| |
return 0
|
| |
|
| |
+
|
| |
def list(subjects):
|
| |
- hosts = [ ]
|
| |
- variables = { }
|
| |
+ hosts = []
|
| |
+ variables = {}
|
| |
for subject in subjects:
|
| |
if subject.endswith((".qcow2", ".qcow2c")):
|
| |
vars = host(subject)
|
| |
if vars:
|
| |
hosts.append(subject)
|
| |
variables[subject] = vars
|
| |
- return { "localhost": { "hosts": hosts, "vars": { } }, "subjects": { "hosts": hosts, "vars": { } }, "_meta": { "hostvars": variables } }
|
| |
+ return {"localhost": {"hosts": hosts, "vars": {}},
|
| |
+ "subjects": {"hosts": hosts, "vars": {}},
|
| |
+ "_meta": {"hostvars": variables}}
|
| |
|
| |
|
| |
- def start_qemu(image, cloudinit, log, portrange=(2222, 5555)):
|
| |
+ def start_qemu(image, cloudinit, log, disk_directory="", portrange=(2222, 5555)):
|
| |
for port in xrange(*portrange):
|
| |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
| |
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
| |
+
|
| |
+ # Shape cmd to sturt qemu
|
| |
+ disk_name = "" if disk_directory == "" else "-hdb"
|
| |
+
|
| |
+ cmd = ("/usr/bin/qemu-system-x86_64 -m 1024 {0} -enable-kvm "
|
| |
+ "-snapshot -cdrom {1} {2} {3} "
|
| |
+ "-net nic,model=virtio -net "
|
| |
+ "user,hostfwd=tcp:127.0.0.3:{4}-:22 -device "
|
| |
+ "isa-serial,chardev=pts2 -chardev "
|
| |
+ "file,id=pts2,path={5} -display none").format(
|
| |
+ image, cloudinit, disk_name, disk_directory, port, log).split()
|
| |
+
|
| |
try:
|
| |
sock.bind(("127.0.0.3", port))
|
| |
+ return subprocess.Popen(cmd, stdout=open(os.devnull, 'w')), port
|
| |
+
|
| |
except IOError:
|
| |
pass
|
| |
- else:
|
| |
- break
|
| |
finally:
|
| |
sock.close()
|
| |
else:
|
| |
raise RuntimeError("unable to find free local port to map SSH to")
|
| |
|
| |
- return subprocess.Popen(["/usr/bin/qemu-system-x86_64", "-m", "1024", image,
|
| |
- "-enable-kvm", "-snapshot", "-cdrom", cloudinit,
|
| |
- "-net", "nic,model=virtio", "-net", "user,hostfwd=tcp:127.0.0.3:{0}-:22".format(port),
|
| |
- "-device", "isa-serial,chardev=pts2", "-chardev", "file,id=pts2,path=" + log,
|
| |
- "-display", "none"], stdout=open(os.devnull, 'w')), port
|
| |
-
|
| |
|
| |
def host(image):
|
| |
null = open(os.devnull, 'w')
|
| |
@@ -134,11 +145,28 @@
|
| |
with open(userdata, 'w') as f:
|
| |
f.write(USER_DATA)
|
| |
|
| |
+ # Create additional disk if environment variable EXTEND_DISK_SIZE
|
| |
+ # was provided.
|
| |
+ # Optional suffixes "k" or "K" (kilobyte, 1024) "M" (megabyte, 1024k) and
|
| |
+ # "G" (gigabyte, 1024M) and T (terabyte, 1024G) are supported.
|
| |
+ disk_size = os.environ.get("EXTEND_DISK_SIZE")
|
| |
+ disk_directory = "{}/atomic-host-disk2-{}".format(directory, disk_size)
|
| |
+ try:
|
| |
+ subprocess.check_call([
|
| |
+ "qemu-img", "create", "-f", "qcow2", disk_directory, disk_size],
|
| |
+ stdout=null)
|
| |
+ sys.stderr.write(
|
| |
+ "\nCreate additional cloud init disk DISK SIZE {}\n".format(
|
| |
+ disk_size))
|
| |
+ except TypeError:
|
| |
+ disk_directory =""
|
| |
+
|
| |
# Create our cloud init so we can log in
|
| |
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)
|
| |
+ "-output", cloudinit, userdata, metadata],
|
| |
+ stdout=null)
|
| |
|
| |
# Determine if virtual machine should be kept available for diagnosis after completion
|
| |
try:
|
| |
@@ -161,7 +189,8 @@
|
| |
cpe = None # for exception scoping
|
| |
for tries in xrange(0, 5):
|
| |
try:
|
| |
- proc, port = start_qemu(image, cloudinit, log)
|
| |
+ proc, port = start_qemu(image, cloudinit, log,
|
| |
+ disk_directory=disk_directory)
|
| |
break
|
| |
except subprocess.CalledProcessError as cpe:
|
| |
time.sleep(1)
|
| |
@@ -170,36 +199,25 @@
|
| |
raise RuntimeError("Could not launch VM for qcow2 image"
|
| |
" '{0}':{1}".format(image, cpe.output))
|
| |
|
| |
+ # The variables
|
| |
+ variables = {"ansible_ssh_port": "{0}".format(port),
|
| |
+ "ansible_ssh_host": "127.0.0.3",
|
| |
+ "ansible_ssh_user": "root",
|
| |
+ "ansible_ssh_pass": "foobar",
|
| |
+ "ansible_ssh_private_key_file": identity,
|
| |
+ "ansible_ssh_common_args": "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"}
|
| |
+
|
| |
+ # Write out a handy inventory file, for our use and for debugging
|
| |
+ args = " ".join(["{0}='{1}'".format(*item) for item in variables.items()])
|
| |
+ inventory = os.path.join(directory, "inventory")
|
| |
+ with open(inventory, "w") as f:
|
| |
+ f.write("[subjects]\nlocalhost {1}\n".format(image, args))
|
| |
+
|
| |
+ # Wait for ssh to come up
|
| |
+ ping = ["/usr/bin/ansible", "--inventory", inventory, "localhost", "--module-name", "raw", "--args", "/bin/true"]
|
| |
+
|
| |
for tries in xrange(0, 30):
|
| |
try:
|
| |
- # The variables
|
| |
- variables = {
|
| |
- "ansible_ssh_port": "{0}".format(port),
|
| |
- "ansible_ssh_host": "127.0.0.3",
|
| |
- "ansible_ssh_user": "root",
|
| |
- "ansible_ssh_pass": "foobar",
|
| |
- "ansible_ssh_private_key_file": identity,
|
| |
- "ansible_ssh_common_args": "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no"
|
| |
- }
|
| |
-
|
| |
- # Write out a handy inventory file, for our use and for debugging
|
| |
- args = " ".join([ "{0}='{1}'".format(*item) for item in variables.items() ])
|
| |
- inventory = os.path.join(directory, "inventory")
|
| |
- with open(inventory, "w") as f:
|
| |
- f.write("[subjects]\nlocalhost {1}\n".format(image, args))
|
| |
-
|
| |
- # Wait for ssh to come up
|
| |
- ping = [
|
| |
- "/usr/bin/ansible",
|
| |
- "--inventory",
|
| |
- inventory,
|
| |
- "localhost",
|
| |
- "--module-name",
|
| |
- "raw",
|
| |
- "--args",
|
| |
- "/bin/true"
|
| |
- ]
|
| |
-
|
| |
(pid, ret) = os.waitpid(proc.pid, os.WNOHANG)
|
| |
if pid != 0:
|
| |
raise RuntimeError("qemu failed to launch qcow2 image: {0}".format(image))
|
| |
@@ -233,16 +251,16 @@
|
| |
# Now wait for the parent process to go away, then kill the VM
|
| |
while True:
|
| |
time.sleep(3)
|
| |
-
|
| |
try:
|
| |
os.kill(ppid, 0)
|
| |
os.kill(proc.pid, 0)
|
| |
except OSError:
|
| |
- break # Either of the processes no longer exist
|
| |
+ break # Either of the processes no longer exist
|
| |
|
| |
if diagnose:
|
| |
sys.stderr.write("\n")
|
| |
- sys.stderr.write("DIAGNOSE: ssh -p {0} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@{1} # password: {2}\n".format(port, "127.0.0.3", "foobar"))
|
| |
+ sys.stderr.write("DIAGNOSE: ssh -p {0} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null "
|
| |
+ "root@{1} # password: {2}\n".format(port, "127.0.0.3", "foobar"))
|
| |
sys.stderr.write("DIAGNOSE: export ANSIBLE_INVENTORY={0}\n".format(inventory))
|
| |
sys.stderr.write("DIAGNOSE: kill {0} # when finished\n".format(os.getpid()))
|
| |
|
| |
@@ -261,5 +279,6 @@
|
| |
shutil.rmtree(directory)
|
| |
sys.exit(0)
|
| |
|
| |
+
|
| |
if __name__ == '__main__':
|
| |
sys.exit(main(sys.argv))
|
| |