[virt-tools-list] [virt-manager PATCH][RFC] Introduction of cloud-init configuration in virt-install
Athina Plaskasoviti
athina.plaskasoviti at gmail.com
Wed Jun 19 13:00:41 UTC 2019
For now, virt-install responds to the --install is_cloud=yes,no_install=yes
to initiate cloud image installation.
Signed-off-by: Athina Plaskasoviti <athina.plaskasoviti at gmail.com>
---
virt-install | 4 +++-
virtinst/cli.py | 2 ++
virtinst/install/cloudinit.py | 29 +++++++++++++++++++++++++++++
virtinst/install/installer.py | 14 +++++++++++++-
virtinst/install/installerinject.py | 13 ++++++++-----
5 files changed, 55 insertions(+), 7 deletions(-)
create mode 100644 virtinst/install/cloudinit.py
diff --git a/virt-install b/virt-install
index ee2b9006..1be0b91c 100755
--- a/virt-install
+++ b/virt-install
@@ -399,6 +399,7 @@ def build_installer(options, guest, installdata):
install_kernel_args = installdata.kernel_args
install_os = installdata.os
no_install = installdata.no_install
+ is_cloud = installdata.is_cloud
if installdata.kernel_args:
if installdata.kernel_args_overwrite:
install_kernel_args = installdata.kernel_args
@@ -433,7 +434,8 @@ def build_installer(options, guest, installdata):
install_kernel=install_kernel,
install_initrd=install_initrd,
install_kernel_args=install_kernel_args,
- no_install=no_install)
+ no_install=no_install,
+ is_cloud=is_cloud)
if options.unattended:
unattended_data = cli.parse_unattended(options.unattended)
diff --git a/virtinst/cli.py b/virtinst/cli.py
index 9a1fe2f6..a2a501a5 100644
--- a/virtinst/cli.py
+++ b/virtinst/cli.py
@@ -1580,6 +1580,7 @@ class ParserInstall(VirtCLIParser):
is_onoff=True)
cls.add_arg("os", "os")
cls.add_arg("no_install", "no_install", is_onoff=True)
+ cls.add_arg("is_cloud", "is_cloud", is_onoff=True)
class InstallData:
@@ -1592,6 +1593,7 @@ class InstallData:
self.os = None
self.is_set = False
self.no_install = None
+ self.is_cloud = None
def parse_install(optstr):
diff --git a/virtinst/install/cloudinit.py b/virtinst/install/cloudinit.py
new file mode 100644
index 00000000..76e11735
--- /dev/null
+++ b/virtinst/install/cloudinit.py
@@ -0,0 +1,29 @@
+import os
+import subprocess
+import yaml
+import string
+
+
+def create_metadata(file_name, hostname=None):
+ if hostname:
+ instance = hostname
+ else:
+ hostname = instance = "localhost"
+
+ with open(file_name, "w") as f:
+ yaml.dump({'instance-id': instance, 'hostname': hostname}, f)
+
+
+def create_userdata(file_name, username=None, password=None):
+ if not password:
+ password = "password"
+
+ userdata_dictionary = {'password': password}
+
+ with open(file_name, "w+") as f:
+ f.write("#cloud-config\n")
+ if username:
+ yaml.dump({'name': username}, f)
+ yaml.dump(userdata_dictionary, f, allow_unicode=True,
+ default_flow_style=False, sort_keys=False)
+ f.writelines(["chpasswd: { expire: False }\n", "runcmd:\n", "- [ sudo, touch, /etc/cloud/cloud-init.disabled ]"])
diff --git a/virtinst/install/installer.py b/virtinst/install/installer.py
index a5c7a708..3d9f2a7e 100644
--- a/virtinst/install/installer.py
+++ b/virtinst/install/installer.py
@@ -16,6 +16,7 @@ from ..devices import DeviceDisk
from ..osdict import OSDB
from ..logger import log
from .. import progress
+from .cloudinit import create_metadata, create_userdata
def _make_testsuite_path(path):
@@ -49,7 +50,7 @@ class Installer(object):
def __init__(self, conn, cdrom=None, location=None, install_bootdev=None,
location_kernel=None, location_initrd=None,
install_kernel=None, install_initrd=None, install_kernel_args=None,
- no_install=None):
+ no_install=None, is_cloud=None):
self.conn = conn
# Entry point for virt-manager 'Customize' wizard to change autostart
@@ -63,6 +64,7 @@ class Installer(object):
self._install_bootdev = install_bootdev
self._no_install = no_install
+ self._is_cloud = is_cloud
self._treemedia = None
self._treemedia_bootconfig = None
@@ -266,6 +268,16 @@ class Installer(object):
elif unattended_script:
self._prepare_unattended_data(guest, unattended_script)
+ elif self._is_cloud:
+ metadata = "meta-data"
+ userdata = "user-data"
+ create_metadata(metadata)
+ create_userdata(userdata)
+ iso = perform_cdrom_injections([metadata, userdata],
+ guest.conn.get_app_cache_dir(), label="cloud")
+ self._tmpfiles.append(iso)
+ self._add_unattended_install_cdrom_device(guest, iso)
+
def _cleanup(self, guest):
if self._treemedia:
self._treemedia.cleanup(guest)
diff --git a/virtinst/install/installerinject.py b/virtinst/install/installerinject.py
index d7cfcfb4..d34dfab9 100644
--- a/virtinst/install/installerinject.py
+++ b/virtinst/install/installerinject.py
@@ -44,19 +44,22 @@ def _run_initrd_commands(initrd, tempdir):
log.debug("gzip stderr=%s", gziperr)
-def _run_iso_commands(iso, tempdir):
+def _run_iso_commands(iso, tempdir, label=None):
cmd = ["genisoimage",
"-o", iso,
"-J",
"-input-charset", "utf8",
"-rational-rock",
tempdir]
+ if label is "cloud":
+ volid = ["-V", "cidata"]
+ cmd[3:1] = volid
log.debug("Running iso build command: %s", cmd)
output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
log.debug("cmd output: %s", output)
-def _perform_generic_injections(injections, scratchdir, media, cb):
+def _perform_generic_injections(injections, scratchdir, media, cb, label=None):
if not injections:
return
@@ -74,7 +77,7 @@ def _perform_generic_injections(injections, scratchdir, media, cb):
filename, dst, media)
shutil.copy(filename, os.path.join(tempdir, dst))
- return cb(media, tempdir)
+ return cb(media, tempdir, label)
finally:
shutil.rmtree(tempdir)
@@ -87,7 +90,7 @@ def perform_initrd_injections(initrd, injections, scratchdir):
_run_initrd_commands)
-def perform_cdrom_injections(injections, scratchdir):
+def perform_cdrom_injections(injections, scratchdir, label=None):
"""
Insert files into the root directory of a generated cdrom
"""
@@ -98,7 +101,7 @@ def perform_cdrom_injections(injections, scratchdir):
try:
_perform_generic_injections(injections, scratchdir, iso,
- _run_iso_commands)
+ _run_iso_commands, label)
except Exception: # pragma: no cover
os.unlink(iso)
raise
--
2.20.1
More information about the virt-tools-list
mailing list