support reading network interface config from DataSourceNoCloud
document usage of DataSourceNoCloud from vfat or iso disk.
This commit is contained in:
parent
f176213004
commit
e8db8f6320
@ -26,6 +26,7 @@
|
||||
- DataSourceOVF: only search for OVF data on ISO9660 filesystems (LP: #898373)
|
||||
- DataSourceConfigDrive: support getting data from openstack config drive (LP: #857378)
|
||||
- DataSourceNoCloud: support seed from external disk of ISO or vfat (LP: #857378)
|
||||
- DataSourceNoCloud: support inserting /etc/network/interfaces
|
||||
0.6.2:
|
||||
- fix bug where update was not done unless update was explicitly set.
|
||||
It would not be run if 'upgrade' or packages were set to be installed
|
||||
|
@ -24,6 +24,7 @@ from cloudinit import seeddir as base_seeddir
|
||||
from cloudinit import log
|
||||
import cloudinit.util as util
|
||||
import errno
|
||||
import subprocess
|
||||
|
||||
|
||||
class DataSourceNoCloud(DataSource.DataSource):
|
||||
@ -31,6 +32,7 @@ class DataSourceNoCloud(DataSource.DataSource):
|
||||
userdata = None
|
||||
userdata_raw = None
|
||||
supported_seed_starts = ("/", "file://")
|
||||
dsmode = "local"
|
||||
seed = None
|
||||
cmdline_id = "ds=nocloud"
|
||||
seeddir = base_seeddir + '/nocloud'
|
||||
@ -42,7 +44,7 @@ class DataSourceNoCloud(DataSource.DataSource):
|
||||
|
||||
def get_data(self):
|
||||
defaults = {
|
||||
"instance-id": "nocloud"
|
||||
"instance-id": "nocloud", "dsmode": "net"
|
||||
}
|
||||
|
||||
found = []
|
||||
@ -84,14 +86,20 @@ class DataSourceNoCloud(DataSource.DataSource):
|
||||
except OSError, e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
except util.mountFailedError:
|
||||
log.warn("Failed to mount %s when looking for seed" % dev)
|
||||
|
||||
# there was no indication on kernel cmdline or data
|
||||
# in the seeddir suggesting this handler should be used.
|
||||
if len(found) == 0:
|
||||
return False
|
||||
|
||||
seeded_interfaces = None
|
||||
|
||||
# the special argument "seedfrom" indicates we should
|
||||
# attempt to seed the userdata / metadata from its value
|
||||
# its primarily value is in allowing the user to type less
|
||||
# on the command line, ie: ds=nocloud;s=http://bit.ly/abcdefg
|
||||
if "seedfrom" in md:
|
||||
seedfrom = md["seedfrom"]
|
||||
seedfound = False
|
||||
@ -104,6 +112,9 @@ class DataSourceNoCloud(DataSource.DataSource):
|
||||
(seedfrom, self.__class__))
|
||||
return False
|
||||
|
||||
if 'network-interfaces' in md:
|
||||
seeded_interfaces = self.dsmode
|
||||
|
||||
# this could throw errors, but the user told us to do it
|
||||
# so if errors are raised, let them raise
|
||||
(md_seed, ud) = util.read_seeded(seedfrom, timeout=None)
|
||||
@ -114,10 +125,35 @@ class DataSourceNoCloud(DataSource.DataSource):
|
||||
found.append(seedfrom)
|
||||
|
||||
md = util.mergedict(md, defaults)
|
||||
|
||||
# update the network-interfaces if metadata had 'network-interfaces'
|
||||
# entry and this is the local datasource, or 'seedfrom' was used
|
||||
# and the source of the seed was self.dsmode
|
||||
# ('local' for NoCloud, 'net' for NoCloudNet')
|
||||
if ('network-interfaces' in md and
|
||||
(self.dsmode in ("local", seeded_interfaces))):
|
||||
log.info("updating network interfaces from nocloud")
|
||||
|
||||
util.write_file("/etc/network/interfaces",
|
||||
md['network-interfaces'])
|
||||
try:
|
||||
(out, err) = util.subp(['ifup', '--all'])
|
||||
if len(out) or len(err):
|
||||
log.warn("ifup --all had stderr: %s" % err)
|
||||
|
||||
except subprocess.CalledProcessError as exc:
|
||||
log.warn("ifup --all failed: %s" % (exc.output[1]))
|
||||
|
||||
self.seed = ",".join(found)
|
||||
self.metadata = md
|
||||
self.userdata_raw = ud
|
||||
return True
|
||||
|
||||
if md['dsmode'] == self.dsmode:
|
||||
return True
|
||||
|
||||
log.debug("%s: not claiming datasource, dsmode=%s" %
|
||||
(self, md['dsmode']))
|
||||
return False
|
||||
|
||||
|
||||
# returns true or false indicating if cmdline indicated
|
||||
@ -166,6 +202,7 @@ class DataSourceNoCloudNet(DataSourceNoCloud):
|
||||
cmdline_id = "ds=nocloud-net"
|
||||
supported_seed_starts = ("http://", "https://", "ftp://")
|
||||
seeddir = base_seeddir + '/nocloud-net'
|
||||
dsmode = "net"
|
||||
|
||||
|
||||
datasources = (
|
||||
|
55
doc/nocloud/README
Normal file
55
doc/nocloud/README
Normal file
@ -0,0 +1,55 @@
|
||||
The data source 'NoCloud' and 'NoCloudNet' allow the user to provide user-data
|
||||
and meta-data to the instance without running a network service (or even without
|
||||
having a network at all)
|
||||
|
||||
You can provide meta-data and user-data to a local vm boot via files on a vfat
|
||||
or iso9660 filesystem. These user-data and meta-data files are expected to be
|
||||
in the format described in doc/example/seed/README . Basically, user-data is
|
||||
simply user-data and meta-data is a yaml formated file representing what you'd
|
||||
find in the EC2 metadata service.
|
||||
|
||||
Given a disk 12.04 cloud image in 'disk.img', you can create a sufficient disk
|
||||
by following the example below.
|
||||
|
||||
## create user-data and meta-data files that will be used
|
||||
## to modify image on first boot
|
||||
$ { echo instance-id: iid-local01; echo local-hostname: cloudimg; } > meta-data
|
||||
|
||||
$ printf "#cloud-config\npassword: passw0rd\nchpasswd: { expire: False }\nssh_pwauth: True\n" > user-data
|
||||
|
||||
## create a disk to attach with some user-data and meta-data
|
||||
$ genisoimage -output seed.iso -volid cidata -joliet -rock user-data meta-data
|
||||
|
||||
## alternatively, create a vfat filesystem with same files
|
||||
## $ truncate --size 2M seed.img
|
||||
## $ mkfs.vfat -n cidata seed.img
|
||||
## $ mcopy -oi seed.img user-data meta-data ::
|
||||
|
||||
## create a new qcow image to boot, backed by your original image
|
||||
$ qemu-img create -f qcow2 -b disk.img boot-disk.img
|
||||
|
||||
## boot the image and login as 'ubuntu' with password 'passw0rd'
|
||||
## note, passw0rd was set as password through the user-data above,
|
||||
## there is no password set on these images.
|
||||
$ kvm -m 256 \
|
||||
-net nic -net user,hostfwd=tcp::2222-:22 \
|
||||
-drive file=boot-disk.img,if=virtio \
|
||||
-drive file=seed.iso,if=virtio
|
||||
|
||||
Note, that the instance-id provided ('iid-local01' above) is what is used to
|
||||
determine if this is "first boot". So if you are making updates to user-data
|
||||
you will also have to change that, or start the disk fresh.
|
||||
|
||||
|
||||
Also, you can inject an /etc/network/interfaces file by providing the content
|
||||
for that file in the 'network-interfaces' field of metadata. Example metadata:
|
||||
instance-id: iid-abcdefg
|
||||
network-interfaces: |
|
||||
iface eth0 inet static
|
||||
address 192.168.1.10
|
||||
network 192.168.1.0
|
||||
netmask 255.255.255.0
|
||||
broadcast 192.168.1.255
|
||||
gateway 192.168.1.254
|
||||
hostname: myhost
|
||||
|
Loading…
Reference in New Issue
Block a user