Beispiel #1
0
    def _get_devices(self, label):
        if util.is_FreeBSD():
            devlist = [
                p for p in ['/dev/msdosfs/' + label, '/dev/iso9660/' + label]
                if os.path.exists(p)
            ]
        elif util.is_NetBSD():
            out, _err = util.subp(['sysctl', '-n', 'hw.disknames'], rcs=[0])
            devlist = []
            for dev in out.split():
                mscdlabel_out, _ = util.subp(['mscdlabel', dev], rcs=[0, 1])
                if ('label "%s"' % label) in mscdlabel_out:
                    devlist.append('/dev/' + dev)
                    devlist.append('/dev/' + dev + 'a')  # NetBSD 7
        else:
            # Query optical drive to get it in blkid cache for 2.6 kernels
            util.find_devs_with(path="/dev/sr0")
            util.find_devs_with(path="/dev/sr1")

            fslist = util.find_devs_with("TYPE=vfat")
            fslist.extend(util.find_devs_with("TYPE=iso9660"))

            label_list = util.find_devs_with("LABEL=%s" % label.upper())
            label_list.extend(util.find_devs_with("LABEL=%s" % label.lower()))

            devlist = list(set(fslist) & set(label_list))
            devlist.sort(reverse=True)
        return devlist
def device_part_info(devpath):
    # convert an entry in /dev/ to parent disk and partition number

    # input of /dev/vdb or /dev/disk/by-label/foo
    # rpath is hopefully a real-ish path in /dev (vda, sdb..)
    rpath = os.path.realpath(devpath)

    bname = os.path.basename(rpath)
    syspath = "/sys/class/block/%s" % bname

    # FreeBSD doesn't know of sysfs so just get everything we need from
    # the device, like /dev/vtbd0p2.
    if util.is_FreeBSD():
        m = re.search('^(/dev/.+)p([0-9])$', devpath)
        return (m.group(1), m.group(2))

    if not os.path.exists(syspath):
        raise ValueError("%s had no syspath (%s)" % (devpath, syspath))

    ptpath = os.path.join(syspath, "partition")
    if not os.path.exists(ptpath):
        raise TypeError("%s not a partition" % devpath)

    ptnum = util.load_file(ptpath).rstrip()

    # for a partition, real syspath is something like:
    # /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1
    rsyspath = os.path.realpath(syspath)
    disksyspath = os.path.dirname(rsyspath)
    bdname = os.path.basename(disksyspath)
    return ('/dev/%s' % bdname, ptnum)
Beispiel #3
0
    def _get_data(self):
        strict_mode, _sleep = read_strict_mode(
            util.get_cfg_by_path(self.sys_cfg, STRICT_ID_PATH,
                                 STRICT_ID_DEFAULT), ("warn", None))

        LOG.debug("strict_mode: %s, cloud_name=%s cloud_platform=%s",
                  strict_mode, self.cloud_name, self.platform)
        if strict_mode == "true" and self.cloud_name == CloudNames.UNKNOWN:
            return False
        elif self.cloud_name == CloudNames.NO_EC2_METADATA:
            return False

        if self.perform_dhcp_setup:  # Setup networking in init-local stage.
            if util.is_FreeBSD():
                LOG.debug("FreeBSD doesn't support running dhclient with -sf")
                return False
            try:
                with EphemeralDHCPv4(self.fallback_interface):
                    self._crawled_metadata = util.log_time(
                        logfunc=LOG.debug, msg='Crawl of metadata service',
                        func=self.crawl_metadata)
            except NoDHCPLeaseError:
                return False
        else:
            self._crawled_metadata = util.log_time(
                logfunc=LOG.debug, msg='Crawl of metadata service',
                func=self.crawl_metadata)
        if not self._crawled_metadata:
            return False
        self.metadata = self._crawled_metadata.get('meta-data', None)
        self.userdata_raw = self._crawled_metadata.get('user-data', None)
        self.identity = self._crawled_metadata.get(
            'dynamic', {}).get('instance-identity', {}).get('document', {})
        return True
Beispiel #4
0
    def _get_data(self):
        strict_mode, _sleep = read_strict_mode(
            util.get_cfg_by_path(self.sys_cfg, STRICT_ID_PATH,
                                 STRICT_ID_DEFAULT), ("warn", None))

        LOG.debug("strict_mode: %s, cloud_name=%s cloud_platform=%s",
                  strict_mode, self.cloud_name, self.platform)
        if strict_mode == "true" and self.cloud_name == CloudNames.UNKNOWN:
            return False
        elif self.cloud_name == CloudNames.NO_EC2_METADATA:
            return False

        if self.perform_dhcp_setup:  # Setup networking in init-local stage.
            if util.is_FreeBSD():
                LOG.debug("FreeBSD doesn't support running dhclient with -sf")
                return False
            try:
                with EphemeralDHCPv4(self.fallback_interface):
                    self._crawled_metadata = util.log_time(
                        logfunc=LOG.debug, msg='Crawl of metadata service',
                        func=self.crawl_metadata)
            except NoDHCPLeaseError:
                return False
        else:
            self._crawled_metadata = util.log_time(
                logfunc=LOG.debug, msg='Crawl of metadata service',
                func=self.crawl_metadata)
        if not self._crawled_metadata:
            return False
        self.metadata = self._crawled_metadata.get('meta-data', None)
        self.userdata_raw = self._crawled_metadata.get('user-data', None)
        self.identity = self._crawled_metadata.get(
            'dynamic', {}).get('instance-identity', {}).get('document', {})
        return True
def perform_hostname_bounce(hostname, cfg, prev_hostname):
    # set the hostname to 'hostname' if it is not already set to that.
    # then, if policy is not off, bounce the interface using command
    # Returns True if the network was bounced, False otherwise.
    command = cfg['command']
    interface = cfg['interface']
    policy = cfg['policy']

    msg = ("hostname=%s policy=%s interface=%s" %
           (hostname, policy, interface))
    env = os.environ.copy()
    env['interface'] = interface
    env['hostname'] = hostname
    env['old_hostname'] = prev_hostname

    if command == "builtin":
        if util.is_FreeBSD():
            command = BOUNCE_COMMAND_FREEBSD
        elif util.which('ifup'):
            command = BOUNCE_COMMAND_IFUP
        else:
            LOG.debug(
                "Skipping network bounce: ifupdown utils aren't present.")
            # Don't bounce as networkd handles hostname DDNS updates
            return False
    LOG.debug("pubhname: publishing hostname [%s]", msg)
    shell = not isinstance(command, (list, tuple))
    # capture=False, see comments in bug 1202758 and bug 1206164.
    util.log_time(logfunc=LOG.debug, msg="publishing hostname",
                  get_uptime=True, func=util.subp,
                  kwargs={'args': command, 'shell': shell, 'capture': False,
                          'env': env})
    return True
Beispiel #6
0
    def _get_data(self):
        seed_ret = {}
        if util.read_optional_seed(seed_ret, base=(self.seed_dir + "/")):
            self.userdata_raw = seed_ret['user-data']
            self.metadata = seed_ret['meta-data']
            LOG.debug("Using seeded ec2 data from %s", self.seed_dir)
            self._cloud_platform = Platforms.SEEDED
            return True

        strict_mode, _sleep = read_strict_mode(
            util.get_cfg_by_path(self.sys_cfg, STRICT_ID_PATH,
                                 STRICT_ID_DEFAULT), ("warn", None))

        LOG.debug("strict_mode: %s, cloud_platform=%s",
                  strict_mode, self.cloud_platform)
        if strict_mode == "true" and self.cloud_platform == Platforms.UNKNOWN:
            return False
        elif self.cloud_platform == Platforms.NO_EC2_METADATA:
            return False

        if self.perform_dhcp_setup:  # Setup networking in init-local stage.
            if util.is_FreeBSD():
                LOG.debug("FreeBSD doesn't support running dhclient with -sf")
                return False
            try:
                with EphemeralDHCPv4(self.fallback_interface):
                    return util.log_time(
                        logfunc=LOG.debug, msg='Crawl of metadata service',
                        func=self._crawl_metadata)
            except NoDHCPLeaseError:
                return False
        else:
            return self._crawl_metadata()
Beispiel #7
0
def get_interfaces_by_mac():
    if util.is_FreeBSD():
        return get_interfaces_by_mac_on_freebsd()
    elif util.is_NetBSD():
        return get_interfaces_by_mac_on_netbsd()
    else:
        return get_interfaces_by_mac_on_linux()
Beispiel #8
0
def find_fallback_nic(blacklist_drivers=None):
    """Return the name of the 'fallback' network device."""
    if util.is_FreeBSD():
        return find_fallback_nic_on_freebsd(blacklist_drivers)
    elif util.is_NetBSD() or util.is_OpenBSD():
        return find_fallback_nic_on_netbsd_or_openbsd(blacklist_drivers)
    else:
        return find_fallback_nic_on_linux(blacklist_drivers)
Beispiel #9
0
def chpasswd(distro, plist_in, hashed=False):
    if util.is_FreeBSD():
        for pentry in plist_in.splitlines():
            u, p = pentry.split(":")
            distro.set_passwd(u, p, hashed=hashed)
    else:
        cmd = ['chpasswd'] + (['-e'] if hashed else [])
        util.subp(cmd, plist_in)
Beispiel #10
0
def find_fallback_nic(
    blacklist_drivers: Optional[List[str]] = None, ) -> Optional[str]:
    """Get the name of the 'fallback' network device."""
    if util.is_FreeBSD() or util.is_DragonFlyBSD():
        return find_fallback_nic_on_freebsd(blacklist_drivers)
    elif util.is_NetBSD() or util.is_OpenBSD():
        return find_fallback_nic_on_netbsd_or_openbsd(blacklist_drivers)
    else:
        return find_fallback_nic_on_linux(blacklist_drivers)
def _get_random_seed():
    """Return content random seed file if available, otherwise,
       return None."""
    # azure / hyper-v provides random data here
    # TODO. find the seed on FreeBSD platform
    # now update ds_cfg to reflect contents pass in config
    if util.is_FreeBSD():
        return None
    return util.load_file("/sys/firmware/acpi/tables/OEM0",
                          quiet=True, decode=False)
Beispiel #12
0
def find_candidate_nics(
    blacklist_drivers: Optional[List[str]] = None, ) -> List[str]:
    """Get the list of network interfaces viable for networking.

    @return List of interfaces, sorted naturally.
    """
    if util.is_FreeBSD() or util.is_DragonFlyBSD():
        return find_candidate_nics_on_freebsd(blacklist_drivers)
    elif util.is_NetBSD() or util.is_OpenBSD():
        return find_candidate_nics_on_netbsd_or_openbsd(blacklist_drivers)
    else:
        return find_candidate_nics_on_linux(blacklist_drivers)
Beispiel #13
0
def list_possible_azure_ds_devs():
    devlist = []
    if util.is_FreeBSD():
        cdrom_dev = "/dev/cd0"
        if _check_freebsd_cdrom(cdrom_dev):
            return [cdrom_dev]
    else:
        for fstype in ("iso9660", "udf"):
            devlist.extend(util.find_devs_with("TYPE=%s" % fstype))

    devlist.sort(reverse=True)
    return devlist
Beispiel #14
0
def get_devicelist():
    if util.is_FreeBSD():
        return list(get_interfaces_by_mac().values())

    try:
        devs = os.listdir(get_sys_class_path())
    except OSError as e:
        if e.errno == errno.ENOENT:
            devs = []
        else:
            raise
    return devs
Beispiel #15
0
def get_interfaces_by_mac(blacklist_drivers=None) -> dict:
    if util.is_FreeBSD():
        return get_interfaces_by_mac_on_freebsd(
            blacklist_drivers=blacklist_drivers)
    elif util.is_NetBSD():
        return get_interfaces_by_mac_on_netbsd(
            blacklist_drivers=blacklist_drivers)
    elif util.is_OpenBSD():
        return get_interfaces_by_mac_on_openbsd(
            blacklist_drivers=blacklist_drivers)
    else:
        return get_interfaces_by_mac_on_linux(
            blacklist_drivers=blacklist_drivers)
Beispiel #16
0
def givecmdline(pid):
    # Returns the cmdline for the given process id. In Linux we can use procfs
    # for this but on BSD there is /usr/bin/procstat.
    try:
        # Example output from procstat -c 1
        #   PID COMM             ARGS
        #     1 init             /bin/init --
        if util.is_FreeBSD():
            (output, _err) = subp.subp(["procstat", "-c", str(pid)])
            line = output.splitlines()[1]
            m = re.search(r"\d+ (\w|\.|-)+\s+(/\w.+)", line)
            return m.group(2)
        else:
            return util.load_file("/proc/%s/cmdline" % pid)
    except IOError:
        return None
def givecmdline(pid):
    # Returns the cmdline for the given process id. In Linux we can use procfs
    # for this but on BSD there is /usr/bin/procstat.
    try:
        # Example output from procstat -c 1
        #   PID COMM             ARGS
        #     1 init             /bin/init --
        if util.is_FreeBSD():
            (output, _err) = util.subp(['procstat', '-c', str(pid)])
            line = output.splitlines()[1]
            m = re.search(r'\d+ (\w|\.|-)+\s+(/\w.+)', line)
            return m.group(2)
        else:
            return util.load_file("/proc/%s/cmdline" % pid)
    except IOError:
        return None
Beispiel #18
0
    def _get_data(self):
        seed_ret = {}
        if util.read_optional_seed(seed_ret, base=(self.seed_dir + "/")):
            self.userdata_raw = seed_ret['user-data']
            self.metadata = seed_ret['meta-data']
            LOG.debug("Using seeded ec2 data from %s", self.seed_dir)
            self._cloud_platform = Platforms.SEEDED
            return True

        strict_mode, _sleep = read_strict_mode(
            util.get_cfg_by_path(self.sys_cfg, STRICT_ID_PATH,
                                 STRICT_ID_DEFAULT), ("warn", None))

        LOG.debug("strict_mode: %s, cloud_platform=%s", strict_mode,
                  self.cloud_platform)
        if strict_mode == "true" and self.cloud_platform == Platforms.UNKNOWN:
            return False
        elif self.cloud_platform == Platforms.NO_EC2_METADATA:
            return False

        if self.get_network_metadata:  # Setup networking in init-local stage.
            if util.is_FreeBSD():
                LOG.debug("FreeBSD doesn't support running dhclient with -sf")
                return False
            dhcp_leases = dhcp.maybe_perform_dhcp_discovery(
                self.fallback_interface)
            if not dhcp_leases:
                # DataSourceEc2Local failed in init-local stage. DataSourceEc2
                # will still run in init-network stage.
                return False
            dhcp_opts = dhcp_leases[-1]
            net_params = {
                'interface': dhcp_opts.get('interface'),
                'ip': dhcp_opts.get('fixed-address'),
                'prefix_or_mask': dhcp_opts.get('subnet-mask'),
                'broadcast': dhcp_opts.get('broadcast-address'),
                'router': dhcp_opts.get('routers')
            }
            with net.EphemeralIPv4Network(**net_params):
                return util.log_time(logfunc=LOG.debug,
                                     msg='Crawl of metadata service',
                                     func=self._crawl_metadata)
        else:
            return self._crawl_metadata()
Beispiel #19
0
def read_dmi_data(key):
    """
    Wrapper for reading DMI data.

    If running in a container return None.  This is because DMI data is
    assumed to be not useful in a container as it does not represent the
    container but rather the host.

    This will do the following (returning the first that produces a
    result):
        1) Use a mapping to translate `key` from dmidecode naming to
           sysfs naming and look in /sys/class/dmi/... for a value.
        2) Use `key` as a sysfs key directly and look in /sys/class/dmi/...
        3) Fall-back to passing `key` to `dmidecode --string`.

    If all of the above fail to find a value, None will be returned.
    """

    if is_container():
        return None

    if is_FreeBSD():
        return _read_kenv(key)

    syspath_value = _read_dmi_syspath(key)
    if syspath_value is not None:
        return syspath_value

    def is_x86(arch):
        return (arch == 'x86_64' or (arch[0] == 'i' and arch[2:] == '86'))

    # running dmidecode can be problematic on some arches (LP: #1243287)
    uname_arch = os.uname()[4]
    if not (is_x86(uname_arch) or uname_arch in ('aarch64', 'amd64')):
        LOG.debug("dmidata is not supported on %s", uname_arch)
        return None

    dmidecode_path = subp.which('dmidecode')
    if dmidecode_path:
        return _call_dmidecode(key, dmidecode_path)

    LOG.debug("did not find either path %s or dmidecode command",
              DMI_SYS_PATH)
    return None
    def _get_devices(self, label):
        if util.is_FreeBSD():
            devlist = [
                p for p in ['/dev/msdosfs/' + label, '/dev/iso9660/' + label]
                if os.path.exists(p)]
        else:
            # Query optical drive to get it in blkid cache for 2.6 kernels
            util.find_devs_with(path="/dev/sr0")
            util.find_devs_with(path="/dev/sr1")

            fslist = util.find_devs_with("TYPE=vfat")
            fslist.extend(util.find_devs_with("TYPE=iso9660"))

            label_list = util.find_devs_with("LABEL=%s" % label.upper())
            label_list.extend(util.find_devs_with("LABEL=%s" % label.lower()))

            devlist = list(set(fslist) & set(label_list))
            devlist.sort(reverse=True)
        return devlist
Beispiel #21
0
    def __init__(self, cfg):

        # constants tailored for FreeBSD
        if util.is_FreeBSD():
            self.pkg_name = "py-salt"
            self.srv_name = "salt_minion"
            self.conf_dir = "/usr/local/etc/salt"
        # constants for any other OS
        else:
            self.pkg_name = "salt-minion"
            self.srv_name = "salt-minion"
            self.conf_dir = "/etc/salt"

        # if there are constants given in cloud config use those
        self.pkg_name = util.get_cfg_option_str(cfg, "pkg_name", self.pkg_name)
        self.conf_dir = util.get_cfg_option_str(cfg, "config_dir",
                                                self.conf_dir)
        self.srv_name = util.get_cfg_option_str(cfg, "service_name",
                                                self.srv_name)
Beispiel #22
0
    def __init__(self, cfg):

        # constants tailored for FreeBSD
        if util.is_FreeBSD():
            self.pkg_name = 'py36-salt'
            self.srv_name = 'salt_minion'
            self.conf_dir = '/usr/local/etc/salt'
        # constants for any other OS
        else:
            self.pkg_name = 'salt-minion'
            self.srv_name = 'salt-minion'
            self.conf_dir = '/etc/salt'

        # if there are constants given in cloud config use those
        self.pkg_name = util.get_cfg_option_str(cfg, 'pkg_name', self.pkg_name)
        self.conf_dir = util.get_cfg_option_str(cfg, 'config_dir',
                                                self.conf_dir)
        self.srv_name = util.get_cfg_option_str(cfg, 'service_name',
                                                self.srv_name)
Beispiel #23
0
def device_part_info(devpath, is_lvm):
    # convert an entry in /dev/ to parent disk and partition number

    # input of /dev/vdb or /dev/disk/by-label/foo
    # rpath is hopefully a real-ish path in /dev (vda, sdb..)
    rpath = os.path.realpath(devpath)

    # first check if this is an LVM and get its PVs
    lvm_rpath = get_pvs_for_lv(devpath)
    if is_lvm and lvm_rpath:
        rpath = lvm_rpath

    bname = os.path.basename(rpath)
    syspath = "/sys/class/block/%s" % bname

    # FreeBSD doesn't know of sysfs so just get everything we need from
    # the device, like /dev/vtbd0p2.
    if util.is_FreeBSD():
        freebsd_part = "/dev/" + util.find_freebsd_part(devpath)
        m = re.search('^(/dev/.+)p([0-9])$', freebsd_part)
        return (m.group(1), m.group(2))

    if not os.path.exists(syspath):
        raise ValueError("%s had no syspath (%s)" % (devpath, syspath))

    ptpath = os.path.join(syspath, "partition")
    if not os.path.exists(ptpath):
        raise TypeError("%s not a partition" % devpath)

    ptnum = util.load_file(ptpath).rstrip()

    # for a partition, real syspath is something like:
    # /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1
    rsyspath = os.path.realpath(syspath)
    disksyspath = os.path.dirname(rsyspath)

    diskmajmin = util.load_file(os.path.join(disksyspath, "dev")).rstrip()
    diskdevpath = os.path.realpath("/dev/block/%s" % diskmajmin)

    # diskdevpath has something like 253:0
    # and udev has put links in /dev/block/253:0 to the device name in /dev/
    return diskdevpath, ptnum
Beispiel #24
0
    def __init__(self, cfg):

        # constants tailored for FreeBSD
        if util.is_FreeBSD():
            self.pkg_name = 'py27-salt'
            self.srv_name = 'salt_minion'
            self.conf_dir = '/usr/local/etc/salt'
        # constants for any other OS
        else:
            self.pkg_name = 'salt-minion'
            self.srv_name = 'salt-minion'
            self.conf_dir = '/etc/salt'

        # if there are constants given in cloud config use those
        self.pkg_name = util.get_cfg_option_str(cfg, 'pkg_name',
                                                self.pkg_name)
        self.conf_dir = util.get_cfg_option_str(cfg, 'config_dir',
                                                self.conf_dir)
        self.srv_name = util.get_cfg_option_str(cfg, 'service_name',
                                                self.srv_name)
Beispiel #25
0
def dist_check_timestamp():
    """
    Determine which init system a particular linux distro is using.
    Each init system (systemd, etc) has a different way of
    providing timestamps.

    :return: timestamps of kernelboot, kernelendboot, and cloud-initstart
    or TIMESTAMP_UNKNOWN if the timestamps cannot be retrieved.
    """

    if uses_systemd():
        return gather_timestamps_using_systemd()

    # Use dmesg to get timestamps if the distro does not have systemd
    if util.is_FreeBSD() or "gentoo" in util.system_info()["system"].lower():
        return gather_timestamps_using_dmesg()

    # this distro doesn't fit anything that is supported by cloud-init. just
    # return error codes
    return TIMESTAMP_UNKNOWN
Beispiel #26
0
def list_possible_azure_ds_devs():
    # return a sorted list of devices that might have a azure datasource
    devlist = []
    if util.is_FreeBSD():
        cdrom_dev = "/dev/cd0"
        try:
            util.subp([
                "mount", "-o", "ro", "-t", "udf", cdrom_dev,
                "/mnt/cdrom/secure"
            ])
        except util.ProcessExecutionError:
            LOG.debug("Fail to mount cd")
            return devlist
        util.subp(["umount", "/mnt/cdrom/secure"])
        devlist.append(cdrom_dev)
    else:
        for fstype in ("iso9660", "udf"):
            devlist.extend(util.find_devs_with("TYPE=%s" % fstype))

    devlist.sort(reverse=True)
    return devlist
Beispiel #27
0
def device_part_info(devpath):
    # convert an entry in /dev/ to parent disk and partition number

    # input of /dev/vdb or /dev/disk/by-label/foo
    # rpath is hopefully a real-ish path in /dev (vda, sdb..)
    rpath = os.path.realpath(devpath)

    bname = os.path.basename(rpath)
    syspath = "/sys/class/block/%s" % bname

    # FreeBSD doesn't know of sysfs so just get everything we need from
    # the device, like /dev/vtbd0p2.
    if util.is_FreeBSD():
        m = re.search('^(/dev/.+)p([0-9])$', devpath)
        return (m.group(1), m.group(2))

    if not os.path.exists(syspath):
        raise ValueError("%s had no syspath (%s)" % (devpath, syspath))

    ptpath = os.path.join(syspath, "partition")
    if not os.path.exists(ptpath):
        raise TypeError("%s not a partition" % devpath)

    ptnum = util.load_file(ptpath).rstrip()

    # for a partition, real syspath is something like:
    # /sys/devices/pci0000:00/0000:00:04.0/virtio1/block/vda/vda1
    rsyspath = os.path.realpath(syspath)
    disksyspath = os.path.dirname(rsyspath)

    diskmajmin = util.load_file(os.path.join(disksyspath, "dev")).rstrip()
    diskdevpath = os.path.realpath("/dev/block/%s" % diskmajmin)

    # diskdevpath has something like 253:0
    # and udev has put links in /dev/block/253:0 to the device name in /dev/
    return (diskdevpath, ptnum)
Beispiel #28
0
def _get_dhcp_endpoint_option_name():
    if util.is_FreeBSD():
        azure_endpoint = "option-245"
    else:
        azure_endpoint = "unknown-245"
    return azure_endpoint
Beispiel #29
0
    def crawl_metadata(self):
        """Walk all instance metadata sources returning a dict on success.

        @return: A dictionary of any metadata content for this instance.
        @raise: InvalidMetaDataException when the expected metadata service is
            unavailable, broken or disabled.
        """
        crawled_data = {}
        # azure removes/ejects the cdrom containing the ovf-env.xml
        # file on reboot.  So, in order to successfully reboot we
        # need to look in the datadir and consider that valid
        ddir = self.ds_cfg['data_dir']

        candidates = [self.seed_dir]
        if os.path.isfile(REPROVISION_MARKER_FILE):
            candidates.insert(0, "IMDS")
        candidates.extend(list_possible_azure_ds_devs())
        if ddir:
            candidates.append(ddir)

        found = None
        reprovision = False
        for cdev in candidates:
            try:
                if cdev == "IMDS":
                    ret = None
                    reprovision = True
                elif cdev.startswith("/dev/"):
                    if util.is_FreeBSD():
                        ret = util.mount_cb(cdev,
                                            load_azure_ds_dir,
                                            mtype="udf",
                                            sync=False)
                    else:
                        ret = util.mount_cb(cdev, load_azure_ds_dir)
                else:
                    ret = load_azure_ds_dir(cdev)

            except NonAzureDataSource:
                continue
            except BrokenAzureDataSource as exc:
                msg = 'BrokenAzureDataSource: %s' % exc
                raise sources.InvalidMetaDataException(msg)
            except util.MountFailedError:
                LOG.warning("%s was not mountable", cdev)
                continue

            perform_reprovision = reprovision or self._should_reprovision(ret)
            if perform_reprovision:
                if util.is_FreeBSD():
                    msg = "Free BSD is not supported for PPS VMs"
                    LOG.error(msg)
                    raise sources.InvalidMetaDataException(msg)
                ret = self._reprovision()
            imds_md = get_metadata_from_imds(self.fallback_interface,
                                             retries=10)
            (md, userdata_raw, cfg, files) = ret
            self.seed = cdev
            crawled_data.update({
                'cfg':
                cfg,
                'files':
                files,
                'metadata':
                util.mergemanydict([md, {
                    'imds': imds_md
                }]),
                'userdata_raw':
                userdata_raw
            })
            found = cdev

            LOG.debug("found datasource in %s", cdev)
            break

        if not found:
            raise sources.InvalidMetaDataException('No Azure metadata found')

        if found == ddir:
            LOG.debug("using files cached in %s", ddir)

        seed = _get_random_seed()
        if seed:
            crawled_data['metadata']['random_seed'] = seed
        crawled_data['metadata']['instance-id'] = util.read_dmi_data(
            'system-uuid')

        if perform_reprovision:
            LOG.info("Reporting ready to Azure after getting ReprovisionData")
            use_cached_ephemeral = (net.is_up(self.fallback_interface) and
                                    getattr(self, '_ephemeral_dhcp_ctx', None))
            if use_cached_ephemeral:
                self._report_ready(lease=self._ephemeral_dhcp_ctx.lease)
                self._ephemeral_dhcp_ctx.clean_network()  # Teardown ephemeral
            else:
                with EphemeralDHCPv4() as lease:
                    self._report_ready(lease=lease)

        return crawled_data
Beispiel #30
0
def _get_dhcp_endpoint_option_name():
    if util.is_FreeBSD():
        azure_endpoint = "option-245"
    else:
        azure_endpoint = "unknown-245"
    return azure_endpoint
Beispiel #31
0
            return None
        return devname
    # try to find /dev/XX from 'storvsc' device
    storvsc = "storvsc{0}".format(storvscid)
    scbusx = find_busdev_from_disk(camcontrol_b_out, storvsc)
    if scbusx:
        devname = find_dev_from_busdev(camcontrol_out, scbusx)
        if devname is None:
            LOG.debug("Fail to find /dev/daX")
            return None
        return devname
    return None


# update the FreeBSD specific information
if util.is_FreeBSD():
    DEFAULT_PRIMARY_NIC = 'hn0'
    LEASE_FILE = '/var/db/dhclient.leases.hn0'
    DEFAULT_FS = 'freebsd-ufs'
    res_disk = get_resource_disk_on_freebsd(1)
    if res_disk is not None:
        LOG.debug("resource disk is not None")
        RESOURCE_DISK_PATH = "/dev/" + res_disk
    else:
        LOG.debug("resource disk is None")

BUILTIN_DS_CONFIG = {
    'agent_command': AGENT_START_BUILTIN,
    'data_dir': AGENT_SEED_DIR,
    'set_hostname': True,
    'hostname_bounce': {
    def _get_data(self):
        found = None
        md = {}
        results = {}
        for sdir in (self.seed_dir, "/config-drive"):
            if not os.path.isdir(sdir):
                continue
            try:
                results = read_config_drive(sdir)
                found = sdir
                break
            except openstack.NonReadable:
                util.logexc(LOG, "Failed reading config drive from %s", sdir)

        if not found:
            dslist = self.sys_cfg.get('datasource_list')
            for dev in find_candidate_devs(dslist=dslist):
                try:
                    if util.is_FreeBSD() and dev.startswith("/dev/cd"):
                        mtype = "cd9660"
                    else:
                        mtype = None
                    results = util.mount_cb(dev, read_config_drive,
                                            mtype=mtype)
                    found = dev
                except openstack.NonReadable:
                    pass
                except util.MountFailedError:
                    pass
                except openstack.BrokenMetadata:
                    util.logexc(LOG, "Broken config drive: %s", dev)
                if found:
                    break
        if not found:
            return False

        md = results.get('metadata', {})
        md = util.mergemanydict([md, DEFAULT_METADATA])

        self.dsmode = self._determine_dsmode(
            [results.get('dsmode'), self.ds_cfg.get('dsmode'),
             sources.DSMODE_PASS if results['version'] == 1 else None])

        if self.dsmode == sources.DSMODE_DISABLED:
            return False

        prev_iid = get_previous_iid(self.paths)
        cur_iid = md['instance-id']
        if prev_iid != cur_iid:
            # better would be to handle this centrally, allowing
            # the datasource to do something on new instance id
            # note, networking is only rendered here if dsmode is DSMODE_PASS
            # which means "DISABLED, but render files and networking"
            on_first_boot(results, distro=self.distro,
                          network=self.dsmode == sources.DSMODE_PASS)

        # This is legacy and sneaky.  If dsmode is 'pass' then do not claim
        # the datasource was used, even though we did run on_first_boot above.
        if self.dsmode == sources.DSMODE_PASS:
            LOG.debug("%s: not claiming datasource, dsmode=%s", self,
                      self.dsmode)
            return False

        self.source = found
        self.metadata = md
        self.ec2_metadata = results.get('ec2-metadata')
        self.userdata_raw = results.get('userdata')
        self.version = results['version']
        self.files.update(results.get('files', {}))

        vd = results.get('vendordata')
        self.vendordata_pure = vd
        try:
            self.vendordata_raw = sources.convert_vendordata(vd)
        except ValueError as e:
            LOG.warning("Invalid content in vendor-data: %s", e)
            self.vendordata_raw = None

        # network_config is an /etc/network/interfaces formated file and is
        # obsolete compared to networkdata (from network_data.json) but both
        # might be present.
        self.network_eni = results.get("network_config")
        self.network_json = results.get('networkdata')
        return True
    def _get_data(self):
        found = None
        md = {}
        results = {}
        for sdir in (self.seed_dir, "/config-drive"):
            if not os.path.isdir(sdir):
                continue
            try:
                results = read_config_drive(sdir)
                found = sdir
                break
            except openstack.NonReadable:
                util.logexc(LOG, "Failed reading config drive from %s", sdir)

        if not found:
            dslist = self.sys_cfg.get('datasource_list')
            for dev in find_candidate_devs(dslist=dslist):
                try:
                    if util.is_FreeBSD() and dev.startswith("/dev/cd"):
                        mtype = "cd9660"
                    else:
                        mtype = None
                    results = util.mount_cb(dev,
                                            read_config_drive,
                                            mtype=mtype)
                    found = dev
                except openstack.NonReadable:
                    pass
                except util.MountFailedError:
                    pass
                except openstack.BrokenMetadata:
                    util.logexc(LOG, "Broken config drive: %s", dev)
                if found:
                    break
        if not found:
            return False

        md = results.get('metadata', {})
        md = util.mergemanydict([md, DEFAULT_METADATA])

        self.dsmode = self._determine_dsmode([
            results.get('dsmode'),
            self.ds_cfg.get('dsmode'),
            sources.DSMODE_PASS if results['version'] == 1 else None
        ])

        if self.dsmode == sources.DSMODE_DISABLED:
            return False

        prev_iid = get_previous_iid(self.paths)
        cur_iid = md['instance-id']
        if prev_iid != cur_iid:
            # better would be to handle this centrally, allowing
            # the datasource to do something on new instance id
            # note, networking is only rendered here if dsmode is DSMODE_PASS
            # which means "DISABLED, but render files and networking"
            on_first_boot(results,
                          distro=self.distro,
                          network=self.dsmode == sources.DSMODE_PASS)

        # This is legacy and sneaky.  If dsmode is 'pass' then do not claim
        # the datasource was used, even though we did run on_first_boot above.
        if self.dsmode == sources.DSMODE_PASS:
            LOG.debug("%s: not claiming datasource, dsmode=%s", self,
                      self.dsmode)
            return False

        self.source = found
        self.metadata = md
        self.ec2_metadata = results.get('ec2-metadata')
        self.userdata_raw = results.get('userdata')
        self.version = results['version']
        self.files.update(results.get('files', {}))

        vd = results.get('vendordata')
        self.vendordata_pure = vd
        try:
            self.vendordata_raw = sources.convert_vendordata(vd)
        except ValueError as e:
            LOG.warning("Invalid content in vendor-data: %s", e)
            self.vendordata_raw = None

        # network_config is an /etc/network/interfaces formated file and is
        # obsolete compared to networkdata (from network_data.json) but both
        # might be present.
        self.network_eni = results.get("network_config")
        self.network_json = results.get('networkdata')
        return True
Beispiel #34
0
    def _get_data(self):
        # azure removes/ejects the cdrom containing the ovf-env.xml
        # file on reboot.  So, in order to successfully reboot we
        # need to look in the datadir and consider that valid
        asset_tag = util.read_dmi_data('chassis-asset-tag')
        if asset_tag != AZURE_CHASSIS_ASSET_TAG:
            LOG.debug("Non-Azure DMI asset tag '%s' discovered.", asset_tag)
            return False

        ddir = self.ds_cfg['data_dir']

        candidates = [self.seed_dir]
        if os.path.isfile(REPROVISION_MARKER_FILE):
            candidates.insert(0, "IMDS")
        candidates.extend(list_possible_azure_ds_devs())
        if ddir:
            candidates.append(ddir)

        found = None
        reprovision = False
        for cdev in candidates:
            try:
                if cdev == "IMDS":
                    ret = None
                    reprovision = True
                elif cdev.startswith("/dev/"):
                    if util.is_FreeBSD():
                        ret = util.mount_cb(cdev,
                                            load_azure_ds_dir,
                                            mtype="udf",
                                            sync=False)
                    else:
                        ret = util.mount_cb(cdev, load_azure_ds_dir)
                else:
                    ret = load_azure_ds_dir(cdev)

            except NonAzureDataSource:
                continue
            except BrokenAzureDataSource as exc:
                raise exc
            except util.MountFailedError:
                LOG.warning("%s was not mountable", cdev)
                continue

            if reprovision or self._should_reprovision(ret):
                ret = self._reprovision()
            (md, self.userdata_raw, cfg, files) = ret
            self.seed = cdev
            self.metadata = util.mergemanydict([md, DEFAULT_METADATA])
            self.cfg = util.mergemanydict([cfg, BUILTIN_CLOUD_CONFIG])
            found = cdev

            LOG.debug("found datasource in %s", cdev)
            break

        if not found:
            return False

        if found == ddir:
            LOG.debug("using files cached in %s", ddir)

        # azure / hyper-v provides random data here
        # TODO. find the seed on FreeBSD platform
        # now update ds_cfg to reflect contents pass in config
        if not util.is_FreeBSD():
            seed = util.load_file("/sys/firmware/acpi/tables/OEM0",
                                  quiet=True,
                                  decode=False)
            if seed:
                self.metadata['random_seed'] = seed

        user_ds_cfg = util.get_cfg_by_path(self.cfg, DS_CFG_PATH, {})
        self.ds_cfg = util.mergemanydict([user_ds_cfg, self.ds_cfg])

        # walinux agent writes files world readable, but expects
        # the directory to be protected.
        write_files(ddir, files, dirmode=0o700)

        self.metadata['instance-id'] = util.read_dmi_data('system-uuid')

        return True
Beispiel #35
0
def available(target=None):
    return util.is_FreeBSD()
Beispiel #36
0
def available(target=None):
    return util.is_FreeBSD() or util.is_DragonFlyBSD()