PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //proc/self/root/opt/saltstack/salt/lib/python3.10/site-packages/salt/modules/seed.py |
""" Virtual machine image management tools """ import logging import os import shutil import tempfile import uuid import salt.config import salt.crypt import salt.syspaths import salt.utils.cloud import salt.utils.files # Set up logging log = logging.getLogger(__name__) # Don't shadow built-in's. __func_alias__ = {"apply_": "apply"} def _file_or_content(file_): if os.path.exists(file_): with salt.utils.files.fopen(file_) as fic: return salt.utils.stringutils.to_unicode(fic.read()) return file_ def prep_bootstrap(mpt): """ Update and get the random script to a random place CLI Example: .. code-block:: bash salt '*' seed.prep_bootstrap /tmp """ # Verify that the boostrap script is downloaded bs_ = __salt__["config.gather_bootstrap_script"]() fpd_ = os.path.join(mpt, "tmp", f"{uuid.uuid4()}") if not os.path.exists(fpd_): os.makedirs(fpd_) os.chmod(fpd_, 0o700) fp_ = os.path.join(fpd_, os.path.basename(bs_)) # Copy script into tmp shutil.copy(bs_, fp_) tmppath = fpd_.replace(mpt, "") return fp_, tmppath def _mount(path, ftype, root=None): mpt = None if ftype == "block": mpt = tempfile.mkdtemp() if not __salt__["mount.mount"](mpt, path): os.rmdir(mpt) return None elif ftype == "dir": return path elif ftype == "file": if "guestfs.mount" in __salt__: util = "guestfs" elif "qemu_nbd.init" in __salt__: util = "qemu_nbd" else: return None mpt = __salt__["mount.mount"](path, device=root, util=util) if not mpt: return None return mpt def _umount(mpt, disk, ftype): if ftype == "block": __salt__["mount.umount"](mpt) os.rmdir(mpt) elif ftype == "file": util = None if "guestfs.mount" in __salt__: util = "guestfs" elif "qemu_nbd.init" in __salt__: util = "qemu_nbd" if util: __salt__["mount.umount"](mpt, device=disk, util=util) def apply_( path, id_=None, config=None, approve_key=True, install=True, prep_install=False, pub_key=None, priv_key=None, mount_point=None, ): """ Seed a location (disk image, directory, or block device) with the minion config, approve the minion's key, and/or install salt-minion. CLI Example: .. code-block:: bash salt 'minion' seed.apply path id [config=config_data] \\ [gen_key=(true|false)] [approve_key=(true|false)] \\ [install=(true|false)] path Full path to the directory, device, or disk image on the target minion's file system. id Minion id with which to seed the path. config Minion configuration options. By default, the 'master' option is set to the target host's 'master'. approve_key Request a pre-approval of the generated minion key. Requires that the salt-master be configured to either auto-accept all keys or expect a signing request from the target host. Default: true. install Install salt-minion, if absent. Default: true. prep_install Prepare the bootstrap script, but don't run it. Default: false """ stats = __salt__["file.stats"](path, follow_symlinks=True) if not stats: return f"{path} does not exist" ftype = stats["type"] path = stats["target"] log.debug("Mounting %s at %s", ftype, path) try: os.makedirs(path) except OSError: # The directory already exists pass mpt = _mount(path, ftype, mount_point) if not mpt: return f"{path} could not be mounted" tmp = os.path.join(mpt, "tmp") log.debug("Attempting to create directory %s", tmp) try: os.makedirs(tmp) except OSError: if not os.path.isdir(tmp): raise cfg_files = mkconfig( config, tmp=tmp, id_=id_, approve_key=approve_key, pub_key=pub_key, priv_key=priv_key, ) if _check_install(mpt): # salt-minion is already installed, just move the config and keys # into place log.info("salt-minion pre-installed on image, configuring as %s", id_) minion_config = salt.config.minion_config(cfg_files["config"]) pki_dir = minion_config["pki_dir"] if not os.path.isdir(os.path.join(mpt, pki_dir.lstrip("/"))): __salt__["file.makedirs"](os.path.join(mpt, pki_dir.lstrip("/"), "")) os.rename( cfg_files["privkey"], os.path.join(mpt, pki_dir.lstrip("/"), "minion.pem") ) os.rename( cfg_files["pubkey"], os.path.join(mpt, pki_dir.lstrip("/"), "minion.pub") ) os.rename(cfg_files["config"], os.path.join(mpt, "etc/salt/minion")) res = True elif install: log.info("Attempting to install salt-minion to %s", mpt) res = _install(mpt) elif prep_install: log.error( "The prep_install option is no longer supported. Please use " "the bootstrap script installed with Salt, located at %s.", salt.syspaths.BOOTSTRAP, ) res = False else: log.warning("No useful action performed on %s", mpt) res = False _umount(mpt, path, ftype) return res def mkconfig( config=None, tmp=None, id_=None, approve_key=True, pub_key=None, priv_key=None ): """ Generate keys and config and put them in a tmp directory. pub_key absolute path or file content of an optional preseeded salt key priv_key absolute path or file content of an optional preseeded salt key CLI Example: .. code-block:: bash salt 'minion' seed.mkconfig [config=config_data] [tmp=tmp_dir] \\ [id_=minion_id] [approve_key=(true|false)] """ if tmp is None: tmp = tempfile.mkdtemp() if config is None: config = {} if "master" not in config and __opts__["master"] != "salt": config["master"] = __opts__["master"] if id_: config["id"] = id_ # Write the new minion's config to a tmp file tmp_config = os.path.join(tmp, "minion") with salt.utils.files.fopen(tmp_config, "w+") as fp_: fp_.write(salt.utils.cloud.salt_config_to_yaml(config)) # Generate keys for the minion pubkeyfn = os.path.join(tmp, "minion.pub") privkeyfn = os.path.join(tmp, "minion.pem") preseeded = pub_key and priv_key if preseeded: log.debug("Writing minion.pub to %s", pubkeyfn) log.debug("Writing minion.pem to %s", privkeyfn) with salt.utils.files.fopen(pubkeyfn, "w") as fic: fic.write(salt.utils.stringutils.to_str(_file_or_content(pub_key))) with salt.utils.files.fopen(privkeyfn, "w") as fic: fic.write(salt.utils.stringutils.to_str(_file_or_content(priv_key))) os.chmod(pubkeyfn, 0o600) os.chmod(privkeyfn, 0o600) else: salt.crypt.gen_keys(tmp, "minion", 2048) if approve_key and not preseeded: with salt.utils.files.fopen(pubkeyfn) as fp_: pubkey = salt.utils.stringutils.to_unicode(fp_.read()) __salt__["pillar.ext"]({"virtkey": [id_, pubkey]}) return {"config": tmp_config, "pubkey": pubkeyfn, "privkey": privkeyfn} def _install(mpt): """ Determine whether salt-minion is installed and, if not, install it. Return True if install is successful or already installed. """ _check_resolv(mpt) boot_, tmppath = prep_bootstrap(mpt) or salt.syspaths.BOOTSTRAP # Exec the chroot command cmd = "if type salt-minion; then exit 0; " cmd += "else sh {} -c /tmp; fi".format(os.path.join(tmppath, "bootstrap-salt.sh")) return not __salt__["cmd.run_chroot"](mpt, cmd, python_shell=True)["retcode"] def _check_resolv(mpt): """ Check that the resolv.conf is present and populated """ resolv = os.path.join(mpt, "etc/resolv.conf") replace = False if os.path.islink(resolv): resolv = os.path.realpath(resolv) if not os.path.isdir(os.path.dirname(resolv)): os.makedirs(os.path.dirname(resolv)) if not os.path.isfile(resolv): replace = True if not replace: with salt.utils.files.fopen(resolv, "rb") as fp_: conts = salt.utils.stringutils.to_unicode(fp_.read()) if "nameserver" not in conts: replace = True if "nameserver 127.0.0.1" in conts: replace = True if replace: shutil.copy("/etc/resolv.conf", resolv) def _check_install(root): sh_ = "/bin/sh" if os.path.isfile(os.path.join(root, "bin/bash")): sh_ = "/bin/bash" cmd = "if ! type salt-minion; then exit 1; fi" cmd = f"chroot '{root}' {sh_} -c '{cmd}'" return not __salt__["cmd.retcode"](cmd, output_loglevel="quiet", python_shell=True)