def wait_on_network(metadata): # Determine whether we need to wait on the network coming online. wait_on_ipv4 = False wait_on_ipv6 = False if WAIT_ON_NETWORK in metadata: wait_on_network = metadata[WAIT_ON_NETWORK] if WAIT_ON_NETWORK_IPV4 in wait_on_network: wait_on_ipv4_val = wait_on_network[WAIT_ON_NETWORK_IPV4] if isinstance(wait_on_ipv4_val, bool): wait_on_ipv4 = wait_on_ipv4_val else: wait_on_ipv4 = util.translate_bool(wait_on_ipv4_val) if WAIT_ON_NETWORK_IPV6 in wait_on_network: wait_on_ipv6_val = wait_on_network[WAIT_ON_NETWORK_IPV6] if isinstance(wait_on_ipv6_val, bool): wait_on_ipv6 = wait_on_ipv6_val else: wait_on_ipv6 = util.translate_bool(wait_on_ipv6_val) # Get information about the host. host_info = None while host_info is None: # This loop + sleep results in two logs every second while waiting # for either ipv4 or ipv6 up. Do we really need to log each iteration # or can we log once and log on successful exit? host_info = get_host_info() network = host_info.get("network") or {} interfaces = network.get("interfaces") or {} by_ipv4 = interfaces.get("by-ipv4") or {} by_ipv6 = interfaces.get("by-ipv6") or {} if wait_on_ipv4: ipv4_ready = len(by_ipv4) > 0 if by_ipv4 else False if not ipv4_ready: host_info = None if wait_on_ipv6: ipv6_ready = len(by_ipv6) > 0 if by_ipv6 else False if not ipv6_ready: host_info = None if host_info is None: LOG.debug( "waiting on network: wait4=%s, ready4=%s, wait6=%s, ready6=%s", wait_on_ipv4, ipv4_ready, wait_on_ipv6, ipv6_ready, ) time.sleep(1) LOG.debug("waiting on network complete") return host_info
def handle(name, cfg, cloud, log, _args): manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False) if util.translate_bool(manage_hosts, addons=['template']): (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return # Render from a template file tpl_fn_name = cloud.get_template_filename("hosts.%s" % (cloud.distro.osfamily)) if not tpl_fn_name: raise RuntimeError(("No hosts template could be" " found for distro %s") % (cloud.distro.osfamily)) templater.render_to_file(tpl_fn_name, '/etc/hosts', {'hostname': hostname, 'fqdn': fqdn}) elif manage_hosts == "localhost": (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return log.debug("Managing localhost in /etc/hosts") cloud.distro.update_etc_hosts(hostname, fqdn) else: log.debug(("Configuration option 'manage_etc_hosts' is not set," " not managing /etc/hosts in module %s"), name)
def install_drivers(cfg, pkg_install_func): if not isinstance(cfg, dict): raise TypeError("'drivers' config expected dict, found '%s': %s" % (type_utils.obj_name(cfg), cfg)) cfgpath = "nvidia/license-accepted" # Call translate_bool to ensure that we treat string values like "yes" as # acceptance and _don't_ treat string values like "nah" as acceptance # because they're True-ish nv_acc = util.translate_bool(util.get_cfg_by_path(cfg, cfgpath)) if not nv_acc: LOG.debug("Not installing NVIDIA drivers. %s=%s", cfgpath, nv_acc) return if not subp.which("ubuntu-drivers"): LOG.debug("'ubuntu-drivers' command not available. " "Installing ubuntu-drivers-common") pkg_install_func(["ubuntu-drivers-common"]) driver_arg = "nvidia" version_cfg = util.get_cfg_by_path(cfg, "nvidia/version") if version_cfg: driver_arg += ":{}".format(version_cfg) LOG.debug( "Installing and activating NVIDIA drivers (%s=%s, version=%s)", cfgpath, nv_acc, version_cfg if version_cfg else "latest", ) # Register and set debconf selection linux/nvidia/latelink = true tdir = temp_utils.mkdtemp(needs_exe=True) debconf_file = os.path.join(tdir, "nvidia.template") debconf_script = os.path.join(tdir, "nvidia-debconf.sh") try: util.write_file(debconf_file, NVIDIA_DEBCONF_CONTENT) util.write_file( debconf_script, util.encode_text(NVIDIA_DRIVER_LATELINK_DEBCONF_SCRIPT), mode=0o755, ) subp.subp([debconf_script, debconf_file]) except Exception as e: util.logexc(LOG, "Failed to register NVIDIA debconf template: %s", str(e)) raise finally: if os.path.isdir(tdir): util.del_dir(tdir) try: subp.subp(["ubuntu-drivers", "install", "--gpgpu", driver_arg]) except subp.ProcessExecutionError as exc: if OLD_UBUNTU_DRIVERS_STDERR_NEEDLE in exc.stderr: LOG.warning("the available version of ubuntu-drivers is" " too old to perform requested driver installation") elif "No drivers found for installation." in exc.stdout: LOG.warning("ubuntu-drivers found no drivers for installation") raise
def handle(name, cfg, cloud, log, _args): manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False) if util.translate_bool(manage_hosts, addons=['template']): (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return # Render from a template file tpl_fn_name = cloud.get_template_filename("hosts.%s" % (cloud.distro.osfamily)) if not tpl_fn_name: raise RuntimeError( ("No hosts template could be" " found for distro %s") % (cloud.distro.osfamily)) templater.render_to_file(tpl_fn_name, '/etc/hosts', { 'hostname': hostname, 'fqdn': fqdn }) elif manage_hosts == "localhost": (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return log.debug("Managing localhost in /etc/hosts") cloud.distro.update_etc_hosts(hostname, fqdn) else: log.debug(("Configuration option 'manage_etc_hosts' is not set," " not managing /etc/hosts in module %s"), name)
def handle(name, cfg, cloud, log, _args): do_migrate = util.get_cfg_option_str(cfg, "migrate", True) if not util.translate_bool(do_migrate): log.debug("Skipping module named %s, migration disabled", name) return sems_moved = _migrate_canon_sems(cloud) log.debug("Migrated %s semaphore files to there canonicalized names", sems_moved) _migrate_legacy_sems(cloud, log)
def handle(name, cfg, cloud, log, _args): manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False) hosts_fn = cloud.distro.hosts_fn if util.translate_bool(manage_hosts, addons=["template"]): if manage_hosts == "template": log.warning( "DEPRECATED: please use manage_etc_hosts: true instead of" " 'template'" ) (hostname, fqdn, _) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warning( "Option 'manage_etc_hosts' was set, but no hostname was found" ) return # Render from a template file tpl_fn_name = cloud.get_template_filename( "hosts.%s" % (cloud.distro.osfamily) ) if not tpl_fn_name: raise RuntimeError( "No hosts template could be found for distro %s" % (cloud.distro.osfamily) ) templater.render_to_file( tpl_fn_name, hosts_fn, {"hostname": hostname, "fqdn": fqdn} ) elif manage_hosts == "localhost": (hostname, fqdn, _) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warning( "Option 'manage_etc_hosts' was set, but no hostname was found" ) return log.debug("Managing localhost in %s", hosts_fn) cloud.distro.update_etc_hosts(hostname, fqdn) else: log.debug( "Configuration option 'manage_etc_hosts' is not set," " not managing %s in module %s", hosts_fn, name, )
def dhcp_domain(self, d, cfg): for item in ['dhcp4domain', 'dhcp6domain']: if item not in d: continue ret = str(d[item]).casefold() try: ret = util.translate_bool(ret) ret = 'yes' if ret else 'no' except ValueError: if ret != 'route': LOG.warning('Invalid dhcp4domain value - %s', ret) ret = 'no' if item == 'dhcp4domain': section = 'DHCPv4' else: section = 'DHCPv6' cfg.update_section(section, 'UseDomains', ret)
def dhcp_domain(self, d, cfg): for item in ["dhcp4domain", "dhcp6domain"]: if item not in d: continue ret = str(d[item]).casefold() try: ret = util.translate_bool(ret) ret = "yes" if ret else "no" except ValueError: if ret != "route": LOG.warning("Invalid dhcp4domain value - %s", ret) ret = "no" if item == "dhcp4domain": section = "DHCPv4" else: section = "DHCPv6" cfg.update_section(section, "UseDomains", ret)
def _extract_preprovisioned_vm_setting(dom): """Read the preprovision flag from the ovf. It should not exist unless true.""" platform_settings_section = find_child( dom.documentElement, lambda n: n.localName == "PlatformSettingsSection") if not platform_settings_section or len(platform_settings_section) == 0: LOG.debug("PlatformSettingsSection not found") return False platform_settings = find_child(platform_settings_section[0], lambda n: n.localName == "PlatformSettings") if not platform_settings or len(platform_settings) == 0: LOG.debug("PlatformSettings not found") return False preprovisionedVm = find_child(platform_settings[0], lambda n: n.localName == "PreprovisionedVm") if not preprovisionedVm or len(preprovisionedVm) == 0: LOG.debug("PreprovisionedVm not found") return False return util.translate_bool(preprovisionedVm[0].firstChild.nodeValue)
def handle(name, cfg, _cloud, log, _args): mycfg = cfg.get("grub_dpkg", cfg.get("grub-dpkg", {})) if not mycfg: mycfg = {} enabled = mycfg.get("enabled", True) if util.is_false(enabled): log.debug("%s disabled by config grub_dpkg/enabled=%s", name, enabled) return idevs = util.get_cfg_option_str(mycfg, "grub-pc/install_devices", None) if idevs is None: idevs = fetch_idevs(log) idevs_empty = mycfg.get("grub-pc/install_devices_empty") if idevs_empty is None: idevs_empty = not idevs elif not isinstance(idevs_empty, bool): log.warning( "DEPRECATED: grub_dpkg: grub-pc/install_devices_empty value of " f"'{idevs_empty}' is not boolean. Use of non-boolean values " "will be removed in a future version of cloud-init.") idevs_empty = util.translate_bool(idevs_empty) idevs_empty = str(idevs_empty).lower() # now idevs and idevs_empty are set to determined values # or, those set by user dconf_sel = ("grub-pc grub-pc/install_devices string %s\n" "grub-pc grub-pc/install_devices_empty boolean %s\n" % (idevs, idevs_empty)) log.debug("Setting grub debconf-set-selections with '%s','%s'" % (idevs, idevs_empty)) try: subp.subp(["debconf-set-selections"], dconf_sel) except Exception: util.logexc(log, "Failed to run debconf-set-selections for grub-dpkg")
def handle(name, cfg, cloud, log, _args): manage_hosts = util.get_cfg_option_str(cfg, "manage_etc_hosts", False) if util.translate_bool(manage_hosts, addons=['template']): (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return # Render from a template file tpl_fn_name = cloud.get_template_filename("hosts.%s" % (cloud.distro.osfamily)) # out_fn = cloud.paths.join(False, '/etc/hosts') out_fn = '/etc/hosts' params = {'hostname': hostname, 'fqdn': fqdn} devs = netinfo.netdev_info() for dev, info in devs.items(): params['dev_' + dev] = info['addr'] templater.render_to_file(tpl_fn_name, out_fn, params) if not tpl_fn_name: raise RuntimeError( ("No hosts template could be" " found for distro %s") % (cloud.distro.osfamily)) # templater.render_to_file(tpl_fn_name, '/etc/hosts', # {'hostname': hostname, 'fqdn': fqdn}) elif manage_hosts == "localhost": (hostname, fqdn) = util.get_hostname_fqdn(cfg, cloud) if not hostname: log.warn(("Option 'manage_etc_hosts' was set," " but no hostname was found")) return log.debug("Managing localhost in /etc/hosts") cloud.distro.update_etc_hosts(hostname, fqdn) else: log.debug(("Configuration option 'manage_etc_hosts' is not set," " not managing /etc/hosts in module %s"), name)
def install_drivers(cfg, pkg_install_func): if not isinstance(cfg, dict): raise TypeError("'drivers' config expected dict, found '%s': %s" % (type_utils.obj_name(cfg), cfg)) cfgpath = 'nvidia/license-accepted' # Call translate_bool to ensure that we treat string values like "yes" as # acceptance and _don't_ treat string values like "nah" as acceptance # because they're True-ish nv_acc = util.translate_bool(util.get_cfg_by_path(cfg, cfgpath)) if not nv_acc: LOG.debug("Not installing NVIDIA drivers. %s=%s", cfgpath, nv_acc) return if not util.which('ubuntu-drivers'): LOG.debug("'ubuntu-drivers' command not available. " "Installing ubuntu-drivers-common") pkg_install_func(['ubuntu-drivers-common']) driver_arg = 'nvidia' version_cfg = util.get_cfg_by_path(cfg, 'nvidia/version') if version_cfg: driver_arg += ':{}'.format(version_cfg) LOG.debug("Installing NVIDIA drivers (%s=%s, version=%s)", cfgpath, nv_acc, version_cfg if version_cfg else 'latest') try: util.subp(['ubuntu-drivers', 'install', '--gpgpu', driver_arg]) except util.ProcessExecutionError as exc: if OLD_UBUNTU_DRIVERS_STDERR_NEEDLE in exc.stderr: LOG.warning('the available version of ubuntu-drivers is' ' too old to perform requested driver installation') elif 'No drivers found for installation.' in exc.stdout: LOG.warning('ubuntu-drivers found no drivers for installation') raise
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] else: resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) if not util.translate_bool(resize_root, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # TODO(harlowja) is the directory ok to be used?? resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run") util.ensure_dir(resize_root_d) # TODO(harlowja): allow what is to be resized to be configurable?? resize_what = "/" result = util.get_mount_info(resize_what, log) if not result: log.warn("Could not determine filesystem type of %s", resize_what) return (devpth, fs_type, mount_point) = result # Ensure the path is a block device. info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) container = util.is_container() if (devpth == "/dev/root" and not os.path.exists(devpth) and not container): devpth = rootdev_from_cmdline(util.get_cmdline()) if devpth is None: log.warn("Unable to find device '/dev/root'") return log.debug("Converted /dev/root to '%s' per kernel cmdline", devpth) try: statret = os.stat(devpth) except OSError as exc: if container and exc.errno == errno.ENOENT: log.debug("Device '%s' did not exist in container. " "cannot resize: %s" % (devpth, info)) elif exc.errno == errno.ENOENT: log.warn("Device '%s' did not exist. cannot resize: %s" % (devpth, info)) else: raise exc return if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): if container: log.debug("device '%s' not a block device in container." " cannot resize: %s" % (devpth, info)) else: log.warn("device '%s' not a block device. cannot resize: %s" % (devpth, info)) return resizer = None fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warn("Not resizing unknown filesystem type %s for %s", fs_type, resize_what) return resize_cmd = resizer(resize_what, devpth) log.debug("Resizing %s (%s) using %s", resize_what, fs_type, ' '.join(resize_cmd)) if resize_root == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb( util.log_time(logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log))) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_root == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s root filesystem (type=%s, val=%s)", action, fs_type, resize_root)
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] else: resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) validate_cloudconfig_schema(cfg, schema) if not util.translate_bool(resize_root, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # TODO(harlowja): allow what is to be resized to be configurable?? resize_what = "/" result = util.get_mount_info(resize_what, log) if not result: log.warning("Could not determine filesystem type of %s", resize_what) return (devpth, fs_type, mount_point) = result # if we have a zfs then our device path at this point # is the zfs label. For example: vmzroot/ROOT/freebsd # we will have to get the zpool name out of this # and set the resize_what variable to the zpool # so the _resize_zfs function gets the right attribute. if fs_type == 'zfs': zpool = devpth.split('/')[0] devpth = util.get_device_info_from_zpool(zpool) if not devpth: return # could not find device from zpool resize_what = zpool info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) devpth = maybe_get_writable_device_path(devpth, info, log) if not devpth: return # devpath was not a writable block device resizer = None if can_skip_resize(fs_type, resize_what, devpth): log.debug("Skip resize filesystem type %s for %s", fs_type, resize_what) return fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warning("Not resizing unknown filesystem type %s for %s", fs_type, resize_what) return resize_cmd = resizer(resize_what, devpth) log.debug("Resizing %s (%s) using %s", resize_what, fs_type, ' '.join(resize_cmd)) if resize_root == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb( util.log_time, logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log)) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_root == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s root filesystem (type=%s, val=%s)", action, fs_type, resize_root)
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] else: resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) validate_cloudconfig_schema(cfg, schema) if not util.translate_bool(resize_root, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # TODO(harlowja): allow what is to be resized to be configurable?? resize_what = "/" result = util.get_mount_info(resize_what, log) if not result: log.warn("Could not determine filesystem type of %s", resize_what) return (devpth, fs_type, mount_point) = result # if we have a zfs then our device path at this point # is the zfs label. For example: vmzroot/ROOT/freebsd # we will have to get the zpool name out of this # and set the resize_what variable to the zpool # so the _resize_zfs function gets the right attribute. if fs_type == 'zfs': zpool = devpth.split('/')[0] devpth = util.get_device_info_from_zpool(zpool) if not devpth: return # could not find device from zpool resize_what = zpool info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) devpth = maybe_get_writable_device_path(devpth, info, log) if not devpth: return # devpath was not a writable block device resizer = None if can_skip_resize(fs_type, resize_what, devpth): log.debug("Skip resize filesystem type %s for %s", fs_type, resize_what) return fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warn("Not resizing unknown filesystem type %s for %s", fs_type, resize_what) return resize_cmd = resizer(resize_what, devpth) log.debug("Resizing %s (%s) using %s", resize_what, fs_type, ' '.join(resize_cmd)) if resize_root == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb( util.log_time, logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log)) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_root == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s root filesystem (type=%s, val=%s)", action, fs_type, resize_root)
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_enabled = args[0] else: resize_enabled = util.get_cfg_option_str(cfg, "resizefs_enabled", True) # Warn about the old-style configuration resize_rootfs_option = util.get_cfg_option_str(cfg, "resize_rootfs") if resize_rootfs_option: log.warning("""The resize_rootfs option is deprecated, please use resizefs_enabled instead!""") resize_enabled = resize_rootfs_option # Renamed to schema_vyos to pass build tests without modifying upstream validate_cloudconfig_schema(cfg, schema_vyos) if not util.translate_bool(resize_enabled, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # Get list of partitions to resize resize_what = util.get_cfg_option_list(cfg, "resizefs_list", RESIZEFS_LIST_DEFAULT) log.debug("Filesystems to resize: %s", resize_what) # Resize all filesystems from resize_what for resize_item in resize_what: result = util.get_mount_info(resize_item, log) if not result: log.warning("Could not determine filesystem type of %s", resize_item) return (devpth, fs_type, mount_point) = result # if we have a zfs then our device path at this point # is the zfs label. For example: vmzroot/ROOT/freebsd # we will have to get the zpool name out of this # and set the resize_item variable to the zpool # so the _resize_zfs function gets the right attribute. if fs_type == 'zfs': zpool = devpth.split('/')[0] devpth = util.get_device_info_from_zpool(zpool) if not devpth: return # could not find device from zpool resize_item = zpool info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_item) log.debug("resize_info: %s" % info) devpth = maybe_get_writable_device_path(devpth, info, log) if not devpth: return # devpath was not a writable block device resizer = None if can_skip_resize(fs_type, resize_item, devpth): log.debug("Skip resize filesystem type %s for %s", fs_type, resize_item) return fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warning("Not resizing unknown filesystem type %s for %s", fs_type, resize_item) return resize_cmd = resizer(resize_item, devpth) log.debug("Resizing %s (%s) using %s", resize_item, fs_type, ' '.join(resize_cmd)) if resize_enabled == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb(util.log_time, logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log)) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_enabled == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s filesystem on %s (type=%s, val=%s)", action, resize_item, fs_type, resize_enabled)
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] else: resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) if not util.translate_bool(resize_root, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # TODO(harlowja) is the directory ok to be used?? resize_root_d = util.get_cfg_option_str(cfg, "resize_rootfs_tmp", "/run") util.ensure_dir(resize_root_d) # TODO(harlowja): allow what is to be resized to be configurable?? resize_what = "/" result = util.get_mount_info(resize_what, log) if not result: log.warn("Could not determine filesystem type of %s", resize_what) return (devpth, fs_type, mount_point) = result info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) container = util.is_container() # Ensure the path is a block device. if (devpth == "/dev/root" and not os.path.exists(devpth) and not container): devpth = util.rootdev_from_cmdline(util.get_cmdline()) if devpth is None: log.warn("Unable to find device '/dev/root'") return log.debug("Converted /dev/root to '%s' per kernel cmdline", devpth) try: statret = os.stat(devpth) except OSError as exc: if container and exc.errno == errno.ENOENT: log.debug( "Device '%s' did not exist in container. " "cannot resize: %s", devpth, info) elif exc.errno == errno.ENOENT: log.warn("Device '%s' did not exist. cannot resize: %s", devpth, info) else: raise exc return if not os.access(devpth, os.W_OK): if container: log.debug("'%s' not writable in container. cannot resize: %s", devpth, info) else: log.warn("'%s' not writable. cannot resize: %s", devpth, info) return if not stat.S_ISBLK(statret.st_mode) and not stat.S_ISCHR(statret.st_mode): if container: log.debug("device '%s' not a block device in container." " cannot resize: %s" % (devpth, info)) else: log.warn("device '%s' not a block device. cannot resize: %s" % (devpth, info)) return resizer = None if can_skip_resize(fs_type, resize_what, devpth): log.debug("Skip resize filesystem type %s for %s", fs_type, resize_what) return fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warn("Not resizing unknown filesystem type %s for %s", fs_type, resize_what) return resize_cmd = resizer(resize_what, devpth) log.debug("Resizing %s (%s) using %s", resize_what, fs_type, ' '.join(resize_cmd)) if resize_root == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb(util.log_time, logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log)) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_root == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s root filesystem (type=%s, val=%s)", action, fs_type, resize_root)
def handle(name, cfg, _cloud, log, args): if len(args) != 0: resize_root = args[0] else: resize_root = util.get_cfg_option_str(cfg, "resize_rootfs", True) validate_cloudconfig_schema(cfg, schema) if not util.translate_bool(resize_root, addons=[NOBLOCK]): log.debug("Skipping module named %s, resizing disabled", name) return # TODO(harlowja): allow what is to be resized to be configurable?? resize_what = "/" result = util.get_mount_info(resize_what, log) if not result: log.warn("Could not determine filesystem type of %s", resize_what) return (devpth, fs_type, mount_point) = result info = "dev=%s mnt_point=%s path=%s" % (devpth, mount_point, resize_what) log.debug("resize_info: %s" % info) devpth = maybe_get_writable_device_path(devpth, info, log) if not devpth: return # devpath was not a writable block device resizer = None if can_skip_resize(fs_type, resize_what, devpth): log.debug("Skip resize filesystem type %s for %s", fs_type, resize_what) return fstype_lc = fs_type.lower() for (pfix, root_cmd) in RESIZE_FS_PREFIXES_CMDS: if fstype_lc.startswith(pfix): resizer = root_cmd break if not resizer: log.warn("Not resizing unknown filesystem type %s for %s", fs_type, resize_what) return resize_cmd = resizer(resize_what, devpth) log.debug("Resizing %s (%s) using %s", resize_what, fs_type, ' '.join(resize_cmd)) if resize_root == NOBLOCK: # Fork to a child that will run # the resize command util.fork_cb(util.log_time, logfunc=log.debug, msg="backgrounded Resizing", func=do_resize, args=(resize_cmd, log)) else: util.log_time(logfunc=log.debug, msg="Resizing", func=do_resize, args=(resize_cmd, log)) action = 'Resized' if resize_root == NOBLOCK: action = 'Resizing (via forking)' log.debug("%s root filesystem (type=%s, val=%s)", action, fs_type, resize_root)