FreeBSD: Support ConfigDrive

Add support for freebsd reading config drive.  Primary work is
related to re-factoring mount_cb to not be so linux specific.

Other changes:
 * declare PATH in freebsd initscripts
 * list dependency on e2fsprogs (for blkid)
 * enable ConfigDrive in freebsd config
 * hosts.freebsd.tmpl added
This commit is contained in:
Scott Moser 2014-09-30 13:26:03 -04:00
commit df03e4a7fa
11 changed files with 115 additions and 36 deletions

View File

@ -37,6 +37,7 @@
- resizefs: fix broken background resizing [Jay Faulkner] (LP: #1338614)
- cc_grub_dpkg: fix EC2 hvm instances to avoid prompt on grub update.
(LP: #1336855)
- FreeBsd: support config drive datasource [Joseph bajin]
0.7.5:
- open 0.7.5
- Add a debug log message around import failures

View File

@ -37,7 +37,9 @@ DEFAULT_METADATA = {
VALID_DSMODES = ("local", "net", "pass", "disabled")
FS_TYPES = ('vfat', 'iso9660')
LABEL_TYPES = ('config-2',)
OPTICAL_DEVICES = tuple(('/dev/sr%s' % i for i in range(0, 2)))
POSSIBLE_MOUNTS = ('sr', 'cd')
OPTICAL_DEVICES = tuple(('/dev/%s%s' % (z, i) for z in POSSIBLE_MOUNTS
for i in range(0, 2)))
class DataSourceConfigDrive(openstack.SourceMixin, sources.DataSource):
@ -70,7 +72,15 @@ class DataSourceConfigDrive(openstack.SourceMixin, sources.DataSource):
if not found:
for dev in find_candidate_devs():
try:
results = util.mount_cb(dev, read_config_drive)
# Set mtype if freebsd and turn off sync
if dev.startswith("/dev/cd"):
mtype = "cd9660"
sync = False
else:
mtype = None
sync = True
results = util.mount_cb(dev, read_config_drive, mtype=mtype,
sync=sync)
found = dev
except openstack.NonReadable:
pass

View File

@ -215,8 +215,7 @@ def transport_iso9660(require_iso=True):
continue
try:
(fname, contents) = util.mount_cb(fullp,
get_ovf_env, mtype=mtype)
(fname, contents) = util.mount_cb(fullp, get_ovf_env, mtype=mtype)
except util.MountFailedError:
LOG.debug("%s not mountable as iso9660" % fullp)
continue

View File

@ -1297,7 +1297,7 @@ def unmounter(umount):
yield umount
finally:
if umount:
umount_cmd = ["umount", '-l', umount]
umount_cmd = ["umount", umount]
subp(umount_cmd)
@ -1346,37 +1346,70 @@ def mount_cb(device, callback, data=None, rw=False, mtype=None, sync=True):
Mount the device, call method 'callback' passing the directory
in which it was mounted, then unmount. Return whatever 'callback'
returned. If data != None, also pass data to callback.
mtype is a filesystem type. it may be a list, string (a single fsname)
or a list of fsnames.
"""
if isinstance(mtype, str):
mtypes = [mtype]
elif isinstance(mtype, (list, tuple)):
mtypes = list(mtype)
elif mtype is None:
mtypes = None
# clean up 'mtype' input a bit based on platform.
platsys = platform.system().lower()
if platsys == "linux":
if mtypes is None:
mtypes = ["auto"]
elif platsys.endswith("bsd"):
if mtypes is None:
mtypes = ['ufs', 'cd9660', 'vfat']
for index, mtype in enumerate(mtypes):
if mtype == "iso9660":
mtypes[index] = "cd9660"
else:
# we cannot do a smart "auto", so just call 'mount' once with no -t
mtypes = ['']
mounted = mounts()
with tempdir() as tmpd:
umount = False
if device in mounted:
mountpoint = mounted[device]['mountpoint']
else:
try:
mountcmd = ['mount']
mountopts = []
if rw:
mountopts.append('rw')
else:
mountopts.append('ro')
if sync:
# This seems like the safe approach to do
# (ie where this is on by default)
mountopts.append("sync")
if mountopts:
mountcmd.extend(["-o", ",".join(mountopts)])
if mtype:
mountcmd.extend(['-t', mtype])
mountcmd.append(device)
mountcmd.append(tmpd)
subp(mountcmd)
umount = tmpd # This forces it to be unmounted (when set)
mountpoint = tmpd
except (IOError, OSError) as exc:
raise MountFailedError(("Failed mounting %s "
"to %s due to: %s") %
for mtype in mtypes:
mountpoint = None
try:
mountcmd = ['mount']
mountopts = []
if rw:
mountopts.append('rw')
else:
mountopts.append('ro')
if sync:
# This seems like the safe approach to do
# (ie where this is on by default)
mountopts.append("sync")
if mountopts:
mountcmd.extend(["-o", ",".join(mountopts)])
if mtype:
mountcmd.extend(['-t', mtype])
mountcmd.append(device)
mountcmd.append(tmpd)
subp(mountcmd)
umount = tmpd # This forces it to be unmounted (when set)
mountpoint = tmpd
break
except (IOError, OSError) as exc:
LOG.debug("Failed mount of '%s' as '%s': %s",
device, mtype, exc)
pass
if not mountpoint:
raise MountFailedError("Failed mounting %s to %s due to: %s" %
(device, tmpd, exc))
# Be nice and ensure it ends with a slash
if not mountpoint.endswith("/"):
mountpoint += "/"

View File

@ -5,7 +5,7 @@ syslog_fix_perms: root:wheel
# This should not be required, but leave it in place until the real cause of
# not beeing able to find -any- datasources is resolved.
datasource_list: ['OpenStack']
datasource_list: ['ConfigDrive', 'OpenStack']
# A set of users which may be applied and/or used by various modules
# when a 'default' entry is found it will reference the 'default_user'

View File

@ -6,6 +6,7 @@
. /etc/rc.subr
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export CLOUD_CFG=/usr/local/etc/cloud/cloud.cfg
name="cloudconfig"

View File

@ -6,6 +6,7 @@
. /etc/rc.subr
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export CLOUD_CFG=/usr/local/etc/cloud/cloud.cfg
name="cloudfinal"

View File

@ -6,6 +6,7 @@
. /etc/rc.subr
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export CLOUD_CFG=/usr/local/etc/cloud/cloud.cfg
name="cloudinit"

View File

@ -6,6 +6,7 @@
. /etc/rc.subr
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
export CLOUD_CFG=/usr/local/etc/cloud/cloud.cfg
name="cloudinitlocal"

View File

@ -0,0 +1,24 @@
## template:jinja
{#
This file /etc/cloud/templates/hosts.freebsd.tmpl is only utilized
if enabled in cloud-config. Specifically, in order to enable it
you need to add the following to config:
manage_etc_hosts: True
-#}
# Your system has configured 'manage_etc_hosts' as True.
# As a result, if you wish for changes to this file to persist
# then you will need to either
# a.) make changes to the master file in /etc/cloud/templates/hosts.freebsd.tmpl
# b.) change or remove the value of 'manage_etc_hosts' in
# /etc/cloud/cloud.cfg or cloud-config from user-data
#
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 {{fqdn}} {{hostname}}
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
# The following lines are desirable for IPv6 capable hosts
::1 {{fqdn}} {{hostname}}
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6

View File

@ -9,15 +9,23 @@ fail() { echo "FAILED:" "$@" 1>&2; exit 1; }
depschecked=/tmp/c-i.dependencieschecked
pkgs="
dmidecode
py27-argparse
py27-boto gpart sudo
py27-configobj py27-yaml
e2fsprogs
gpart
py27-Jinja2
py27-oauth py27-serial
py27-argparse
py27-boto
py27-cheetah
py27-configobj
py27-jsonpatch
py27-jsonpointer
py27-oauth
py27-prettytable
py27-requests py27-six
python py27-cheetah
py27-jsonpointer py27-jsonpatch
py27-requests
py27-serial
py27-six
py27-yaml
python
sudo
"
[ -f "$depschecked" ] || pkg install ${pkgs} || fail "install packages"
touch $depschecked