Merge ~farcaller/cloud-init:nocloud-dmi into cloud-init:master

Proposed by Vladimir Pouzanov
Status: Merged
Approved by: Scott Moser
Approved revision: 9c021fd4eb270a8456786e67d8e817c177a53623
Merged at revision: 802e7cb2da8e2d0225525160e6edd6b58b275b8c
Proposed branch: ~farcaller/cloud-init:nocloud-dmi
Merge into: cloud-init:master
Diff against target: 70 lines (+37/-0)
3 files modified
cloudinit/sources/DataSourceNoCloud.py (+12/-0)
doc/rtd/topics/datasources/nocloud.rst (+22/-0)
tools/ds-identify (+3/-0)
Reviewer Review Type Date Requested Status
Ryan Harper Approve
Server Team CI bot continuous-integration Approve
Review via email: mp+324273@code.launchpad.net

Commit message

NoCloud: support seed of nocloud from smbios information

This allows the user to seed NoCloud in a trivial way from qemu/libvirt, by
using a stock image and passing a single command line flag.
No custom command line, no filesystem modification, no bootstrap disk image.

This is particularly handy now that Ec2 backend is discouraged from use:
https://bugs.launchpad.net/cloud-init/+bug/1660385

LP: #1691772

Description of the change

provide a way to seed NoCloud from network without image modification (bug 1691772).

To post a comment you must log in.
Revision history for this message
Scott Moser (smoser) wrote :

Vladimir,
This looks really good, thank you.

I'd like to update doc/rtd/topics/datasources/nocloud.rst with an example on how to use this directly with a qemu cmdline.

Also I think the kernel cmdline should override the smbios information.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
~farcaller/cloud-init:nocloud-dmi updated
30e6420... by Vladimir Pouzanov <email address hidden>

Added kernel command line / smbios docs to nocloud

d7db02d... by Vladimir Pouzanov <email address hidden>

Prefer command line over DMI

4e6d0db... by Vladimir Pouzanov <email address hidden>

Fixed flake8 linting issues

Revision history for this message
Vladimir Pouzanov (farcaller) wrote :

Updated the docs, ordering, and fixed linter issue.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ryan Harper (raharper) :
review: Needs Fixing
Revision history for this message
Scott Moser (smoser) wrote :

On Fri, 19 May 2017, Ryan Harper wrote:

> > try:
> > + # Parse the system serial label from dmi. If not empty, try parsing
> > + # like the commandline
> > + md = {}
> > + serial = util.read_dmi_data('system-serial-number')
> > + if serial is not None:
>
> Your comment "if not empty" doesn't appear to match the check here.
>
> read_dmi_data may return None, or "" (see _call_dmicode which has a return "" for empty fields)
>
> serial = ""
> That returns True when checking if it is 'not None'; I think just:
>
> if serial
>
> is what we want here instead.

The comment is not right, but the function i think is fine. because
load_cmdline_data will return False on "". We do want to specifically
not pass it None. On None as the cmdline, it will call get_cmdline().

So either way is really ok, but make sure we do not pass None.

Revision history for this message
Ryan Harper (raharper) wrote :

On Fri, May 19, 2017 at 12:27 PM, Scott Moser <email address hidden> wrote:

> On Fri, 19 May 2017, Ryan Harper wrote:
>
> > > try:
> > > + # Parse the system serial label from dmi. If not empty,
> try parsing
> > > + # like the commandline
> > > + md = {}
> > > + serial = util.read_dmi_data('system-serial-number')
> > > + if serial is not None:
> >
> > Your comment "if not empty" doesn't appear to match the check here.
> >
> > read_dmi_data may return None, or "" (see _call_dmicode which has a
> return "" for empty fields)
> >
> > serial = ""
> > That returns True when checking if it is 'not None'; I think just:
> >
> > if serial
> >
> > is what we want here instead.
>
> The comment is not right, but the function i think is fine. because
> load_cmdline_data will return False on "". We do want to specifically
>

Why bother checking the command line for a serial of "" ? That's not going
to do anything productive AFAICT. Surely not calling a function with it
isn't needed
is better than calling it when we know ahead of time that it's not a valid
serial number
we can expect on the command line.

Ryan

~farcaller/cloud-init:nocloud-dmi updated
9c021fd... by Vladimir Pouzanov <email address hidden>

Simplified the condition that verifies correct data in serial field

Revision history for this message
Vladimir Pouzanov (farcaller) wrote :

Fixed.

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

For reference, from the DMTF smbios spec DSP0134_2.7.1, the serial field is a string.
With regard to string length:

  http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf

 NOTE: There is no limit on the length of each individual text string.
 However, the length of the entire structure table (including all strings)
 must be reported in the Structure Table Length field of the SMBIOS
 Structure Table Entry Point which is a WORD field limited to 65,535 bytes.

Revision history for this message
Ryan Harper (raharper) wrote :

Looks good!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/sources/DataSourceNoCloud.py b/cloudinit/sources/DataSourceNoCloud.py
2index c68f6b8..e641244 100644
3--- a/cloudinit/sources/DataSourceNoCloud.py
4+++ b/cloudinit/sources/DataSourceNoCloud.py
5@@ -43,6 +43,18 @@ class DataSourceNoCloud(sources.DataSource):
6 'network-config': None}
7
8 try:
9+ # Parse the system serial label from dmi. If not empty, try parsing
10+ # like the commandline
11+ md = {}
12+ serial = util.read_dmi_data('system-serial-number')
13+ if serial and load_cmdline_data(md, serial):
14+ found.append("dmi")
15+ mydata = _merge_new_seed(mydata, {'meta-data': md})
16+ except Exception:
17+ util.logexc(LOG, "Unable to parse dmi data")
18+ return False
19+
20+ try:
21 # Parse the kernel command line, getting data passed in
22 md = {}
23 if load_cmdline_data(md):
24diff --git a/doc/rtd/topics/datasources/nocloud.rst b/doc/rtd/topics/datasources/nocloud.rst
25index 0159e85..665057f 100644
26--- a/doc/rtd/topics/datasources/nocloud.rst
27+++ b/doc/rtd/topics/datasources/nocloud.rst
28@@ -11,6 +11,28 @@ You can provide meta-data and user-data to a local vm boot via files on a
29 `vfat`_ or `iso9660`_ filesystem. The filesystem volume label must be
30 ``cidata``.
31
32+Alternatively, you can provide meta-data via kernel command line or SMBIOS
33+"serial number" option. The data must be passed in the form of a string:
34+
35+::
36+
37+ ds=nocloud[;key=val;key=val]
38+
39+or
40+
41+::
42+
43+ ds=nocloud-net[;key=val;key=val]
44+
45+e.g. you can pass this option to QEMU:
46+
47+::
48+
49+ -smbios type=1,serial=ds=nocloud-net;s=http://10.10.0.1:8000/
50+
51+to cause NoCloud to fetch the full meta-data from http://10.10.0.1:8000/meta-data
52+after the network initialization is complete.
53+
54 These user-data and meta-data files are expected to be in the following format.
55
56 ::
57diff --git a/tools/ds-identify b/tools/ds-identify
58index aff26eb..b272d18 100755
59--- a/tools/ds-identify
60+++ b/tools/ds-identify
61@@ -544,6 +544,9 @@ dscheck_NoCloud() {
62 case " ${DI_KERNEL_CMDLINE} " in
63 *\ ds=nocloud*) return ${DS_FOUND};;
64 esac
65+ case " ${DI_DMI_PRODUCT_SERIAL} " in
66+ *\ ds=nocloud*) return ${DS_FOUND};;
67+ esac
68 for d in nocloud nocloud-net; do
69 check_seed_dir "$d" meta-data user-data && return ${DS_FOUND}
70 done

Subscribers

People subscribed via source and target branches