[ovirt-users] Add multiple files to a VM via cloud-init

Juan Hernandez jhernand at redhat.com
Fri Oct 31 23:00:08 UTC 2014


On 10/31/2014 06:47 PM, Branimir Pejakovic wrote:
> 
> 
> 
> On Thu, Oct 30, 2014 at 12:52 PM, Branimir Pejakovic
> <branimirp at gmail.com <mailto:branimirp at gmail.com>> wrote:
> 
> 
> 
>     On Thu, Oct 30, 2014 at 12:39 PM, Shahar Havivi <shaharh at redhat.com
>     <mailto:shaharh at redhat.com>> wrote:
> 
>         On 30.10.14 12:30, Branimir Pejakovic wrote:
>         > On Thu, Oct 30, 2014 at 12:02 PM, Shahar Havivi
>         <shaharh at redhat.com <mailto:shaharh at redhat.com>> wrote:
>         >
>         > > On 30.10.14 10:06, Branimir Pejakovic wrote:
>         > > > On Thu, Oct 30, 2014 at 7:22 AM, Shahar Havivi
>         <shaharh at redhat.com <mailto:shaharh at redhat.com>>
>         > > wrote:
>         > > >
>         > > > > On 29.10.14 17:35, Branimir Pejakovic wrote:
>         > > > > > Hi list,
>         > > > > >
>         > > > > > I was wondering is there a way to add multiple files
>         to a vm via
>         > > > > cloud-init
>         > > > > > using python SDK. I was able to add /etc/resolv.conf and
>         > > additionally I
>         > > > > > would like to add config files for NICs (ifcfg-ethX)
>         with appropriate
>         > > > > > values (ip,gw,netmask). I used an example given here:
>         > > > > > http://www.ovirt.org/Features/Cloud-Init_Integration . But
>         > > > > unfortunately I
>         > > > > > cannot do the same thing If I want to write multiple
>         files to a vm in
>         > > > > > params.Action class.
>         > > > > >
>         > > > > > Thank you in advance!
>         > > > > you can use the custom script text box in oVirts
>         cloud-init section,
>         > > > > there you can add any cloud-init section - adding files
>         examples can be
>         > > > > found
>         > > > > here:
>         > > > >
>         > > > >
>         > >
>         http://cloudinit.readthedocs.org/en/latest/topics/examples.html#writing-out-arbitrary-files
>         > > > >
>         > > > >   Shahar Havivi.
>         > > > >
>         > > > >
>         > > > Hi Shahar,
>         > > >
>         > > > Thank you for the reply.
>         > > >
>         > > > To be honest I knew for those scripts but I want to do it
>         in automate
>         > > > fashion just like in that example that I put in my
>         original message. I
>         > > have
>         > > > tried to specify in params.Files class multiple files:
>         > > >
>         > > > vm_file1 = params.Files(file=[params.File(name = 'file1',
>         content =
>         > > > file1_content, type_= 'PLAINTEXT')])
>         > > > vm_file2 = params.Files(file=[params.File(name = 'file2',
>         content =
>         > > > file2_content, type_= 'PLAINTEXT')])
>         > > >
>         > > > and then give them as arguments to params.CloudInit _init_
>         constructor
>         > > > (files=...)  just like in that example above but it seems
>         that I am doing
>         > > > something wrong because it does not write multiple files -
>         it writes only
>         > > > when you specify one file all right. The exception is
>         "Error: 'list'
>         > > object
>         > > > has no attribute 'export'" (I tried to specify those files
>         as a list -
>         > > > files=[vm_file1,vm_file2]).
>         > > >
>         > > > Thanks for any help.
>         > > The custom script is currently the only option to add files
>         via Cloud-Init
>         > >
>         > > Thanks,
>         > >   Shahar Havivi.
>         > >
>         > >
>         > Hi Shahar,
>         >
>         > Granted. But the example in python
>         > http://www.ovirt.org/Features/Cloud-Init_Integration uses
>         custom script :)
>         > I just want to know how to do the same thing in case when I
>         want to write
>         > more than one file to a VM - and yes  - all those multiple
>         files that I
>         > want to write are specified via custom scripts.
>         >
>         > From the link - (The "Python SDK" paragraph: scontent object
>         holds the
>         > custom script):
>         >
>         >  scontent = "write_files:\n-   content: |\n        search
>         > example.com <http://example.com>\n        nameserver
>         10.10.10.1\n        nameserver
>         > 10.10.10.2\n    path: /etc/resolv.conf"
>         >
>         > For example (and just for example), I want to write to
>         /etc/issue and
>         > /etc/hosts not only /etc/resolv.conf. In essence, when vm goes
>         to run-once
>         > mode I want to write more than one file to a vm via Python (using
>         > CloudInit) in automated fashion (and not touching oVirt GUI at
>         all).
>         You don't need to use the GUI,
>         the sdks initialization have custom_script as string which is
>         equivalent to
>         the text box that you see in the GUI, and you can put the same
>         content there
>         (ie multiple files).
>         Is that sufficient enough?
> 
> 
>     Hi Shahar,
> 
>     Thanks! I will try this one. I was not aware of this feature.
>     Although I can see that it was mentioned on the list (my bad).
> 
>     Thank you for your effort! I really do appreciate it!
> 
> 
> 
> Hi,
> 
> Please if somebody can help me because I am pretty stuck. As I said in
> previous posts I used this Python example
> http://www.ovirt.org/Features/Cloud-Init_Integration to set root
> password, hostname and resolv.conf. It worked without any problems for
> 3.4 oVirt version and equivalent Python SDK
> (ovirt-engine-sdk-python-3.4.x.noarch).
> 
> Then, I have tried to write through yuml scripts more conf files than
> just resolv.conf to configure guest. I also saw this post on the list:
> http://lists.ovirt.org/pipermail/users/2014-October/028539.html. So
> based on that, I decided to upgraded oVirt and SDK
> (ovirt-engine-sdk-python-3.5.0.7-1.el6.noarch) to 3.5 version. The
> upgrade itself passed without any problem.
> 
> From that point forward I tried to use custom_script parameter (as
> suggested by Shahar) inside Initialization class and CloudInit class
> without any luck.
> 
> Can somebody please provide a simple Python code to submit yaml script
> to cloud-init?
>  
> Also after the upgrade the example script I mentioned above can only
> change hostname. It does not write resolv.conf anymore nor it sets root
> password. I don't know if something is changed inside methods? For
> example, customization of virtual machine (memory,cpu,high availability,
> pinning to a certain host etc works without any problems).
> 
> Thank you!
> 
> Best regards,
> 
> Branimir
> 

The "custom_script" element doesn't work in combination with cloud-init
and run once. To make it work you have to use cloud-init and a file
element containing your custom script. Here you have an example:

#!/usr/bin/python

import base64
import re

from ovirtsdk.api import API
from ovirtsdk.xml import params

# A simple function to encode using base64 and now new lines:
def encode(s):
   return re.sub("\s+", "", base64.encodestring(s))

# Connect to the server:
api = API(
  url="https://engine35.example.com/ovirt-engine/api",
  username="admin at internal",
  password="redhat123",
  insecure=True,
  debug=True
)

# Find the virtual machine:
myvm = api.vms.get(name="myvm")

# Prepare the cloud-init custom script to write files:
myscript = """\
write_files:
"""

# Append one file:
myscript += """\
- encoding: b64
  content: %s
  owner: root:root
  path: /etc/firstfile.txt
  permissions: '0644'
""" % encode("The content of the first file")

# Append another file:
myscript += """\
- encoding: b64
  content: %s
  owner: root:root
  path: /etc/secondfile.txt
  permissions: '0644'
""" % encode("The content of the second file")

# Prepare the action to trigger initialization using cloud-init:
action = params.Action(
  vm=params.VM(
    initialization=params.Initialization(
      cloud_init=params.CloudInit(
        files=params.Files(
          file=[
            params.File(
              name="myscript",
              type_="plaintext",
              content=myscript
            )
          ]
        )
      )
    )
  )
)

# Start the virtual machine:
myvm.start(action)

# Disconnect from the server:
api.disconnect()

Regarding the problem with the root password we have a bug in 3.5 that
makes this fail. See here:

  https://bugzilla.redhat.com/1156155

The problem is that we are not passing the user name to cloud-init, and
as a result it is changing the default cloud-init user password, not the
root pssword. To workaround the issue you can edit the
"/etc/cloud/cloud.cfg" file of the VM and change the default user name:

  system_info:
  distro: ...
  default_user:
    name: root  <-- Change this from "fedora" or "cloud-init" to root

-- 
Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta
3ºD, 28016 Madrid, Spain
Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.



More information about the Users mailing list