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)
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
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()
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()
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)
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)
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)
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)
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
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
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)
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
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()
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
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)
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)
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
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)
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
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
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)
def _get_dhcp_endpoint_option_name(): if util.is_FreeBSD(): azure_endpoint = "option-245" else: azure_endpoint = "unknown-245" return azure_endpoint
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
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
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
def available(target=None): return util.is_FreeBSD()
def available(target=None): return util.is_FreeBSD() or util.is_DragonFlyBSD()