summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMina Galić <me+git@igalic.co>2020-11-04 15:49:34 +0100
committerGitHub <noreply@github.com>2020-11-04 09:49:34 -0500
commitcf6c36a18de233190996f7c2dde1e04908bad50a (patch)
tree332a0f625ba1699b9fb9ee4d9dd8148f7190f015
parentd1c01c1df94e07afd3843e31b1e1ce670cf07387 (diff)
downloadcloud-init-git-cf6c36a18de233190996f7c2dde1e04908bad50a.tar.gz
split read_fs_info into linux & freebsd parts (#625)
FreeBSD doesn't have blkid, so we want to use geom to list devices and their fstypes and labels. This PR also adds `jail` to the list of is_container() And we now also properly cache geom and blkid output! A test is added to verify the new behaviour by correctly identifying NoCloud on FreeBSD. Co-authored-by: Scott Moser <smoser@brickies.net>
-rw-r--r--tests/unittests/test_ds_identify.py40
-rwxr-xr-xtools/ds-identify106
2 files changed, 137 insertions, 9 deletions
diff --git a/tests/unittests/test_ds_identify.py b/tests/unittests/test_ds_identify.py
index 9314b244..5f8a4a29 100644
--- a/tests/unittests/test_ds_identify.py
+++ b/tests/unittests/test_ds_identify.py
@@ -20,6 +20,8 @@ UNAME_MYSYS = ("Linux bart 4.4.0-62-generic #83-Ubuntu "
UNAME_PPC64EL = ("Linux diamond 4.4.0-83-generic #106-Ubuntu SMP "
"Mon Jun 26 17:53:54 UTC 2017 "
"ppc64le ppc64le ppc64le GNU/Linux")
+UNAME_FREEBSD = ("FreeBSD fbsd12-1 12.1-RELEASE-p10 "
+ "FreeBSD 12.1-RELEASE-p10 GENERIC amd64")
BLKID_EFI_ROOT = """
DEVNAME=/dev/sda1
@@ -80,6 +82,7 @@ MOCK_VIRT_IS_VMWARE = {'name': 'detect_virt', 'RET': 'vmware', 'ret': 0}
MOCK_VIRT_IS_VM_OTHER = {'name': 'detect_virt', 'RET': 'vm-other', 'ret': 0}
MOCK_VIRT_IS_XEN = {'name': 'detect_virt', 'RET': 'xen', 'ret': 0}
MOCK_UNAME_IS_PPC64 = {'name': 'uname', 'out': UNAME_PPC64EL, 'ret': 0}
+MOCK_UNAME_IS_FREEBSD = {'name': 'uname', 'out': UNAME_FREEBSD, 'ret': 0}
shell_true = 0
shell_false = 1
@@ -257,6 +260,10 @@ class TestDsIdentify(DsIdentifyBase):
"""EC2: bobrightbox.com in product_serial is not brightbox'"""
self._test_ds_not_found('Ec2-brightbox-negative')
+ def test_freebsd_nocloud(self):
+ """NoCloud identified on FreeBSD via label by geom."""
+ self._test_ds_found('NoCloud-fbsd')
+
def test_gce_by_product_name(self):
"""GCE identifies itself with product_name."""
self._test_ds_found('GCE')
@@ -725,6 +732,26 @@ def blkid_out(disks=None):
return '\n'.join(lines)
+def geom_out(disks=None):
+ """Convert a list of disk dictionaries into geom content.
+
+ geom called with -a (provider) and -s (script-friendly), will produce the
+ following output:
+
+ gpt/gptboot0 N/A vtbd1p1
+ gpt/swap0 N/A vtbd1p2
+ iso9660/cidata N/A vtbd2
+ """
+ if disks is None:
+ disks = []
+ lines = []
+ for disk in disks:
+ lines.append("%s/%s N/A %s" % (
+ disk["TYPE"], disk["LABEL"], disk["DEVNAME"]))
+ lines.append("")
+ return '\n'.join(lines)
+
+
def _print_run_output(rc, out, err, cfg, files):
"""A helper to print return of TestDsIdentify.
@@ -807,6 +834,19 @@ VALID_CFG = {
'dev/vdb': 'pretend iso content for cidata\n',
}
},
+ 'NoCloud-fbsd': {
+ 'ds': 'NoCloud',
+ 'mocks': [
+ MOCK_VIRT_IS_KVM,
+ MOCK_UNAME_IS_FREEBSD,
+ {'name': 'geom', 'ret': 0,
+ 'out': geom_out(
+ [{'DEVNAME': 'vtbd', 'TYPE': 'iso9660', 'LABEL': 'cidata'}])},
+ ],
+ 'files': {
+ '/dev/vtdb': 'pretend iso content for cidata\n',
+ }
+ },
'NoCloudUpper': {
'ds': 'NoCloud',
'mocks': [
diff --git a/tools/ds-identify b/tools/ds-identify
index 4e5700fc..ec9e775e 100755
--- a/tools/ds-identify
+++ b/tools/ds-identify
@@ -92,7 +92,8 @@ _DI_LOGGED=""
# set DI_MAIN='noop' in environment to source this file with no main called.
DI_MAIN=${DI_MAIN:-main}
-DI_BLKID_OUTPUT=""
+DI_BLKID_EXPORT_OUT=""
+DI_GEOM_LABEL_STATUS_OUT=""
DI_DEFAULT_POLICY="search,found=all,maybe=all,notfound=${DI_DISABLED}"
DI_DEFAULT_POLICY_NO_DMI="search,found=all,maybe=all,notfound=${DI_ENABLED}"
DI_DMI_CHASSIS_ASSET_TAG=""
@@ -231,8 +232,19 @@ ensure_sane_path() {
done
}
-read_fs_info() {
- cached "${DI_BLKID_OUTPUT}" && return 0
+blkid_export() {
+ # call 'blkid -c /dev/null export', set DI_BLKID_EXPORT_OUT
+ cached "$DI_BLKID_EXPORT_OUT" && return 0
+ local out="" ret=0
+ out=$(blkid -c /dev/null -o export) && DI_BLKID_EXPORT_OUT="$out" || {
+ ret=$?
+ error "failed running [$ret]: blkid -c /dev/null -o export"
+ DI_BLKID_EXPORT_OUT="$UNAVAILABLE"
+ }
+ return $ret
+}
+
+read_fs_info_linux() {
# do not rely on links in /dev/disk which might not be present yet.
# Note that blkid < 2.22 (centos6, trusty) do not output DEVNAME.
# that means that DI_ISO9660_DEVS will not be set.
@@ -244,20 +256,23 @@ read_fs_info() {
return
fi
local oifs="$IFS" line="" delim=","
- local ret=0 out="" labels="" dev="" label="" ftype="" isodevs="" uuids=""
- out=$(blkid -c /dev/null -o export) || {
- ret=$?
- error "failed running [$ret]: blkid -c /dev/null -o export"
+ local ret=0 labels="" dev="" label="" ftype="" isodevs="" uuids=""
+
+ blkid_export
+ ret=$?
+ [ "$DI_BLKID_EXPORT_OUT" = "$UNAVAILABLE" ] && {
DI_FS_LABELS="$UNAVAILABLE:error"
DI_ISO9660_DEVS="$UNAVAILABLE:error"
+ DI_FS_UUIDS="$UNAVAILABLE:error"
return $ret
}
+
# 'set --' will collapse multiple consecutive entries in IFS for
# whitespace characters (\n, tab, " ") so we cannot rely on getting
# empty lines in "$@" below.
# shellcheck disable=2086
- { IFS="$CR"; set -- $out; IFS="$oifs"; }
+ { IFS="$CR"; set -- $DI_BLKID_EXPORT_OUT; IFS="$oifs"; }
for line in "$@"; do
case "${line}" in
@@ -281,6 +296,74 @@ read_fs_info() {
DI_ISO9660_DEVS="${isodevs#,}"
}
+geom_label_status_as() {
+ # call 'geom label status -as', set DI_GEOM_LABEL_STATUS_OUT
+ cached "$DI_GEOM_LABEL_STATUS_OUT" && return 0
+ local out="" ret=0
+ out=$(geom label status -as) && DI_GEOM_LABEL_STATUS_OUT="$out" || {
+ ret=$?
+ error "failed running [$ret]: geom label status -as"
+ DI_GEOM_LABEL_STATUS_OUT="$UNAVAILABLE"
+ }
+ return $ret
+}
+
+
+read_fs_info_freebsd() {
+ local oifs="$IFS" line="" delim=","
+ local ret=0 labels="" dev="" label="" ftype="" isodevs=""
+
+ geom_label_status_as
+ ret=$?
+ [ "$DI_GEOM_LABEL_STATUS_OUT" = "$UNAVAILABLE" ] && {
+ DI_FS_LABELS="$UNAVAILABLE:error"
+ DI_ISO9660_DEVS="$UNAVAILABLE:error"
+ return $ret
+ }
+
+ # The expected output looks like this:
+ # gpt/gptboot0 N/A vtbd1p1
+ # gpt/swap0 N/A vtbd1p2
+ # iso9660/cidata N/A vtbd2
+
+ # shellcheck disable=2086
+ { IFS="$CR"; set -- $DI_GEOM_LABEL_STATUS_OUT; IFS="$oifs"; }
+
+ for line in "$@"; do
+ # shellcheck disable=2086
+ set -- $line
+ provider=$1
+ ftype="${provider%/*}"
+ label="${provider#*/}"
+ dev=$3
+
+ [ -n "$dev" -a "$ftype" = "iso9660" ] &&
+ isodevs="${isodevs},${dev}=$label"
+
+ labels="${labels}${label}${delim}"
+ done
+
+ DI_FS_LABELS="${labels%${delim}}"
+ DI_ISO9660_DEVS="${isodevs#,}"
+}
+
+read_fs_info() {
+ # After calling its subfunctions, read_fs_info() will set the following
+ # variables:
+ #
+ # - DI_FS_LABELS
+ # - DI_ISO9660_DEVS
+ # - DI_FS_UUIDS
+
+ if [ "$DI_UNAME_KERNEL_NAME" = "FreeBSD" ]; then
+ read_fs_info_freebsd
+ return $?
+ else
+ read_fs_info_linux
+ return $?
+ fi
+}
+
cached() {
[ -n "$1" ] && _RET="$1" && return || return 1
}
@@ -319,6 +402,11 @@ detect_virt() {
*) virt="$out"
esac
}
+ out=$(sysctl -qn security.jail.jailed 2>/dev/null) && {
+ if [ "$out" = "1" ]; then
+ virt="jail"
+ fi
+ }
fi
_RET="$virt"
}
@@ -331,7 +419,7 @@ read_virt() {
is_container() {
case "${DI_VIRT}" in
- container-other|lxc|lxc-libvirt|systemd-nspawn|docker|rkt) return 0;;
+ container-other|lxc|lxc-libvirt|systemd-nspawn|docker|rkt|jail) return 0;;
*) return 1;;
esac
}