[virt-tools-list] [virt-manager PATCH v3] Introduction of cloud-init configuration in virt-install

Daniel P. Berrangé berrange at redhat.com
Tue Jul 2 09:12:41 UTC 2019


On Fri, Jun 28, 2019 at 07:05:18PM +0300, Athina Plaskasoviti wrote:
> Usage:
> --cloud-init
> 
> Signed-off-by: Athina Plaskasoviti <athina.plaskasoviti at gmail.com>
> ---
>  virt-install                        |  5 +++
>  virtinst/cli.py                     | 25 +++++++++++++
>  virtinst/install/cloudinit.py       | 57 +++++++++++++++++++++++++++++
>  virtinst/install/installer.py       | 17 +++++++++
>  virtinst/install/installerinject.py | 20 +++++-----
>  5 files changed, 115 insertions(+), 9 deletions(-)
>  create mode 100644 virtinst/install/cloudinit.py
> 
> diff --git a/virt-install b/virt-install
> index ee2b9006..1ccf7a31 100755
> --- a/virt-install
> +++ b/virt-install
> @@ -444,6 +444,9 @@ def build_installer(options, guest, installdata):
>          installer.set_initrd_injections(options.initrd_inject)
>      if options.autostart:
>          installer.autostart = True
> +    if options.cloud_init:
> +        cloudinit_data = cli.parse_cloud_init(options.cloud_init)
> +        installer.set_cloudinit_data(cloudinit_data)
>  
>      return installer
>  
> @@ -821,6 +824,8 @@ def parse_args():
>                      help=_("Perform an unattended installation"))
>      insg.add_argument("--install",
>              help=_("Specify fine grained install options"))
> +    insg.add_argument("--cloud-init", nargs="?", const=1,
> +                    help=_("Perform a cloud image installation, configuring cloud-init"))
>  
>      # Takes a URL and just prints to stdout the detected distro name
>      insg.add_argument("--test-media-detection", help=argparse.SUPPRESS)
> diff --git a/virtinst/cli.py b/virtinst/cli.py
> index 9a1fe2f6..9a6badcd 100644
> --- a/virtinst/cli.py
> +++ b/virtinst/cli.py
> @@ -28,6 +28,7 @@ from .nodedev import NodeDevice
>  from .osdict import OSDB
>  from .storage import StoragePool, StorageVolume
>  from .install.unattended import UnattendedData
> +from .install.cloudinit import CloudInitData
>  
>  
>  ##########################
> @@ -1602,6 +1603,30 @@ def parse_install(optstr):
>      return installdata
>  
>  
> +########################
> +# --cloud-init parsing #
> +########################
> +
> +class ParserCloudInit(VirtCLIParser):
> +    cli_arg_name = "cloud-init"
> +
> +    @classmethod
> +    def _init_class(cls, **kwargs):
> +        VirtCLIParser._init_class(**kwargs)
> +        cls.add_arg("root-password", "root_password")
> +
> +
> +def parse_cloud_init(optstr):
> +    ret = CloudInitData()
> +    if optstr == 1:
> +        # This means bare --cloud-init, so there's nothing to parse
> +        return ret
> +
> +    parser = ParserCloudInit(optstr)
> +    parser.parse(ret)
> +    return ret
> +
> +
>  ######################
>  # --location parsing #
>  ######################
> diff --git a/virtinst/install/cloudinit.py b/virtinst/install/cloudinit.py
> new file mode 100644
> index 00000000..41667f4b
> --- /dev/null
> +++ b/virtinst/install/cloudinit.py
> @@ -0,0 +1,57 @@
> +import tempfile
> +import random
> +import string
> +import time
> +from ..logger import log
> +
> +
> +class CloudInitData():
> +    root_password = None
> +
> +
> +def create_metadata(scratchdir, hostname=None):
> +    if hostname:
> +        instance = hostname
> +    else:
> +        hostname = instance = "localhost"
> +    content = 'instance-id: %s\n' % instance
> +    content += 'hostname: %s\n' % hostname
> +    log.debug("Generated cloud-init metadata:\n%s", content)
> +
> +    fileobj = tempfile.NamedTemporaryFile(
> +            prefix="virtinst-", suffix="-metadata",
> +            dir=scratchdir, delete=False)
> +    filename = fileobj.name
> +
> +    with open(filename, "w") as f:
> +        f.write(content)
> +    return filename
> +
> +
> +def create_userdata(scratchdir, cloudinit_data, username=None, password=None):
> +    if not password:
> +        password = ""
> +        for dummy in range(16):
> +            password += random.choice(string.ascii_letters + string.digits)
> +    content = "#cloud-config\n"
> +    if username:
> +        content += "name: %s\n" % username
> +    if cloudinit_data.root_password == "generate":
> +        pass
> +    else:
> +        content += "password: %s\n" % password
> +        log.debug("Generated password for first boot: \n%s", password)
> +        time.sleep(20)
> +    content += "runcmd:\n"
> +    content += "- [ sudo, touch, /etc/cloud/cloud-init.disabled ]\n"
> +    log.debug("Generated cloud-init userdata:\n%s", content)

This message is going to leak the root password too. It is nice to
log the cloud init data though, so we need a fix to scrub the actual
root password from it before logging.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the virt-tools-list mailing list