[virt-tools-list] [virt-manager PATCH][v2][RFC] Introduction of cloud-init configuration in virt-install
Athina Plaskasoviti
athina.plaskasoviti at gmail.com
Fri Jun 21 17:18:45 UTC 2019
Triggered by:
--install is_cloud=yes ... --import
Signed-off-by: Athina Plaskasoviti <athina.plaskasoviti at gmail.com>
---
virt-install | 9 ++++---
virtinst/cli.py | 2 ++
virtinst/install/cloudinit.py | 41 +++++++++++++++++++++++++++++
virtinst/install/installer.py | 16 ++++++++++-
virtinst/install/installerinject.py | 20 +++++++-------
5 files changed, 75 insertions(+), 13 deletions(-)
create mode 100644 virtinst/install/cloudinit.py
diff --git a/virt-install b/virt-install
index ee2b9006..b3608662 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
@@ -417,10 +418,11 @@ def build_installer(options, guest, installdata):
no_install = True
elif options.pxe:
install_bootdev = "network"
+ elif options.import_install:
+ no_install = True
elif installdata.is_set:
pass
- elif (options.import_install or
- options.xmlonly or
+ elif (options.xmlonly or
options.boot):
no_install = True
@@ -433,7 +435,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..25b2a79b
--- /dev/null
+++ b/virtinst/install/cloudinit.py
@@ -0,0 +1,41 @@
+import tempfile
+from ..logger import log
+
+
+def create_metadata(scratchdir, hostname=None):
+ if hostname:
+ instance = hostname
+ else:
+ hostname = instance = "localhost"
+
+ fileobj = tempfile.NamedTemporaryFile(
+ prefix="virtinst-", suffix="-metadata",
+ dir=scratchdir, delete=False)
+ filename = fileobj.name
+
+ with open(filename, "w") as f:
+ log.debug("Writing instance-id and hostname to file meta-data")
+ f.writelines(['instance-id: %s\n' % instance,
+ 'hostname: %s\n' % hostname])
+ return filename
+
+
+def create_userdata(scratchdir, username=None, password=None):
+ if not password:
+ password = "password"
+
+ fileobj = tempfile.NamedTemporaryFile(
+ prefix="virtinst-", suffix="-userdata",
+ dir=scratchdir, delete=False)
+ filename = fileobj.name
+
+ with open(filename, "w+") as f:
+ f.write("#cloud-config\n")
+ if username:
+ log.debug("Writing username to file user-data")
+ f.write("name: %s\n" % username)
+ log.debug("Writing password and cmd for disabling of cloud-init to file user-data")
+ f.writelines(["password: %s\n" % password,
+ "chpasswd: { expire: False }\n", "runcmd:\n",
+ "- [ sudo, touch, /etc/cloud/cloud-init.disabled ]"])
+ return filename
diff --git a/virtinst/install/installer.py b/virtinst/install/installer.py
index a5c7a708..5cc5b685 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,9 @@ class Installer(object):
elif unattended_script:
self._prepare_unattended_data(guest, unattended_script)
+ elif self._is_cloud:
+ self._install_cloud(guest)
+
def _cleanup(self, guest):
if self._treemedia:
self._treemedia.cleanup(guest)
@@ -401,6 +406,15 @@ class Installer(object):
def set_unattended_data(self, unattended_data):
self._unattended_data = unattended_data
+ def _install_cloud(self, guest):
+ metadata = create_metadata(guest.conn.get_app_cache_dir())
+ userdata = create_userdata(guest.conn.get_app_cache_dir())
+
+ iso = perform_cdrom_injections([(metadata, "meta-data"), (userdata, "user-data")],
+ guest.conn.get_app_cache_dir(), cloudinit=True)
+ self._tmpfiles.append(iso)
+ self._add_unattended_install_cdrom_device(guest, iso)
+
##########################
# guest install handling #
diff --git a/virtinst/install/installerinject.py b/virtinst/install/installerinject.py
index d7cfcfb4..7ad4833f 100644
--- a/virtinst/install/installerinject.py
+++ b/virtinst/install/installerinject.py
@@ -44,19 +44,21 @@ def _run_initrd_commands(initrd, tempdir):
log.debug("gzip stderr=%s", gziperr)
-def _run_iso_commands(iso, tempdir):
+def _run_iso_commands(iso, tempdir, cloudinit=False):
cmd = ["genisoimage",
"-o", iso,
"-J",
"-input-charset", "utf8",
- "-rational-rock",
- tempdir]
+ "-rational-rock"]
+ if cloudinit:
+ cmd.extend(["-V", "cidata"])
+ cmd.append(tempdir)
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, cloudinit=False):
if not injections:
return
@@ -74,20 +76,20 @@ 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, cloudinit)
finally:
shutil.rmtree(tempdir)
-def perform_initrd_injections(initrd, injections, scratchdir):
+def perform_initrd_injections(initrd, injections, scratchdir, cloudinit=False):
"""
Insert files into the root directory of the initial ram disk
"""
_perform_generic_injections(injections, scratchdir, initrd,
- _run_initrd_commands)
+ _run_initrd_commands, cloudinit)
-def perform_cdrom_injections(injections, scratchdir):
+def perform_cdrom_injections(injections, scratchdir, cloudinit=False):
"""
Insert files into the root directory of a generated cdrom
"""
@@ -98,7 +100,7 @@ def perform_cdrom_injections(injections, scratchdir):
try:
_perform_generic_injections(injections, scratchdir, iso,
- _run_iso_commands)
+ _run_iso_commands, cloudinit)
except Exception: # pragma: no cover
os.unlink(iso)
raise
--
2.20.1
More information about the virt-tools-list
mailing list