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/smartos_imgadm.py |
""" Module for running imgadm command on SmartOS """ import logging import salt.utils.json import salt.utils.path import salt.utils.platform log = logging.getLogger(__name__) # Function aliases __func_alias__ = { "list_installed": "list", "update_installed": "update", "import_image": "import", } # Define the module's virtual name __virtualname__ = "imgadm" def __virtual__(): """ Provides imgadm only on SmartOS """ if salt.utils.platform.is_smartos_globalzone() and salt.utils.path.which("imgadm"): return __virtualname__ return ( False, f"{__virtualname__} module can only be loaded on SmartOS compute nodes", ) def _exit_status(retcode, stderr=None): """ Translate exit status of imgadm """ ret = { 0: "Successful completion.", 1: "An error occurred." if not stderr else stderr, 2: "Usage error.", 3: "Image not installed.", } return ret[retcode] def _parse_image_meta(image=None, detail=False): ret = None if image and "Error" in image: ret = image elif image and "manifest" in image and "name" in image["manifest"]: name = image["manifest"]["name"] version = image["manifest"]["version"] os = image["manifest"]["os"] description = image["manifest"]["description"] published = image["manifest"]["published_at"] source = image["source"] if image["manifest"]["name"] == "docker-layer": # NOTE: skip docker-layer unless it has a docker:repo and docker:tag name = None docker_repo = None docker_tag = None for tag in image["manifest"]["tags"]: if tag.startswith("docker:tag:") and image["manifest"]["tags"][tag]: docker_tag = tag.split(":")[-1] elif tag == "docker:repo": docker_repo = image["manifest"]["tags"][tag] if docker_repo and docker_tag: name = f"{docker_repo}:{docker_tag}" description = ( "Docker image imported from {repo}:{tag} on {date}.".format( repo=docker_repo, tag=docker_tag, date=published, ) ) if name and detail: ret = { "name": name, "version": version, "os": os, "description": description, "published": published, "source": source, } elif name: ret = "{name}@{version} [{published}]".format( name=name, version=version, published=published, ) else: log.debug("smartos_image - encountered invalid image payload: %s", image) ret = {"Error": "This looks like an orphaned image, image payload was invalid."} return ret def _split_docker_uuid(uuid): """ Split a smartos docker uuid into repo and tag """ if uuid: uuid = uuid.split(":") if len(uuid) == 2: tag = uuid[1] repo = uuid[0] return repo, tag return None, None def _is_uuid(uuid): """ Check if uuid is a valid smartos uuid Example: e69a0918-055d-11e5-8912-e3ceb6df4cf8 """ if uuid and list(len(x) for x in uuid.split("-")) == [8, 4, 4, 4, 12]: return True return False def _is_docker_uuid(uuid): """ Check if uuid is a valid smartos docker uuid Example plexinc/pms-docker:plexpass """ repo, tag = _split_docker_uuid(uuid) return not (not repo and not tag) def version(): """ Return imgadm version CLI Example: .. code-block:: bash salt '*' imgadm.version """ ret = {} cmd = "imgadm --version" res = __salt__["cmd.run"](cmd).splitlines() ret = res[0].split() return ret[-1] def docker_to_uuid(uuid): """ Get the image uuid from an imported docker image .. versionadded:: 2019.2.0 """ if _is_uuid(uuid): return uuid if _is_docker_uuid(uuid): images = list_installed(verbose=True) for image_uuid in images: if "name" not in images[image_uuid]: continue if images[image_uuid]["name"] == uuid: return image_uuid return None def update_installed(uuid=""): """ Gather info on unknown image(s) (locally installed) uuid : string optional uuid of image CLI Example: .. code-block:: bash salt '*' imgadm.update [uuid] """ cmd = f"imgadm update {uuid}".rstrip() __salt__["cmd.run"](cmd) return {} def avail(search=None, verbose=False): """ Return a list of available images search : string search keyword verbose : boolean (False) toggle verbose output CLI Example: .. code-block:: bash salt '*' imgadm.avail [percona] salt '*' imgadm.avail verbose=True """ ret = {} cmd = "imgadm avail -j" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret for image in salt.utils.json.loads(res["stdout"]): if image["manifest"]["disabled"] or not image["manifest"]["public"]: continue if search and search not in image["manifest"]["name"]: # we skip if we are searching but don't have a match continue uuid = image["manifest"]["uuid"] data = _parse_image_meta(image, verbose) if data: ret[uuid] = data return ret def list_installed(verbose=False): """ Return a list of installed images verbose : boolean (False) toggle verbose output .. versionchanged:: 2019.2.0 Docker images are now also listed CLI Example: .. code-block:: bash salt '*' imgadm.list salt '*' imgadm.list docker=True salt '*' imgadm.list verbose=True """ ret = {} cmd = "imgadm list -j" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret for image in salt.utils.json.loads(res["stdout"]): uuid = image["manifest"]["uuid"] data = _parse_image_meta(image, verbose) if data: ret[uuid] = data return ret def show(uuid): """ Show manifest of a given image uuid : string uuid of image CLI Example: .. code-block:: bash salt '*' imgadm.show e42f8c84-bbea-11e2-b920-078fab2aab1f salt '*' imgadm.show plexinc/pms-docker:plexpass """ ret = {} if _is_uuid(uuid) or _is_docker_uuid(uuid): cmd = f"imgadm show {uuid}" res = __salt__["cmd.run_all"](cmd, python_shell=False) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode, res["stderr"]) else: ret = salt.utils.json.loads(res["stdout"]) else: ret["Error"] = f"{uuid} is not a valid uuid." return ret def get(uuid): """ Return info on an installed image uuid : string uuid of image CLI Example: .. code-block:: bash salt '*' imgadm.get e42f8c84-bbea-11e2-b920-078fab2aab1f salt '*' imgadm.get plexinc/pms-docker:plexpass """ ret = {} if _is_docker_uuid(uuid): uuid = docker_to_uuid(uuid) if _is_uuid(uuid): cmd = f"imgadm get {uuid}" res = __salt__["cmd.run_all"](cmd, python_shell=False) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode, res["stderr"]) else: ret = salt.utils.json.loads(res["stdout"]) else: ret["Error"] = f"{uuid} is not a valid uuid." return ret def import_image(uuid, verbose=False): """ Import an image from the repository uuid : string uuid to import verbose : boolean (False) toggle verbose output CLI Example: .. code-block:: bash salt '*' imgadm.import e42f8c84-bbea-11e2-b920-078fab2aab1f [verbose=True] """ ret = {} cmd = f"imgadm import {uuid}" res = __salt__["cmd.run_all"](cmd, python_shell=False) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret uuid = docker_to_uuid(uuid) data = _parse_image_meta(get(uuid), verbose) return {uuid: data} def delete(uuid): """ Remove an installed image uuid : string Specifies uuid to import CLI Example: .. code-block:: bash salt '*' imgadm.delete e42f8c84-bbea-11e2-b920-078fab2aab1f """ ret = {} cmd = f"imgadm delete {uuid}" res = __salt__["cmd.run_all"](cmd, python_shell=False) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret # output: Deleted image d5b3865c-0804-11e5-be21-dbc4ce844ddc result = [] for image in res["stdout"].splitlines(): image = [var for var in image.split(" ") if var] result.append(image[2]) return result def vacuum(verbose=False): """ Remove unused images verbose : boolean (False) toggle verbose output CLI Example: .. code-block:: bash salt '*' imgadm.vacuum [verbose=True] """ ret = {} cmd = "imgadm vacuum -f" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret # output: Deleted image d5b3865c-0804-11e5-be21-dbc4ce844ddc (lx-centos-6@20150601) result = {} for image in res["stdout"].splitlines(): image = [var for var in image.split(" ") if var] result[image[2]] = { "name": image[3][1 : image[3].index("@")], "version": image[3][image[3].index("@") + 1 : -1], } if verbose: return result else: return list(result.keys()) def sources(verbose=False): """ Return a list of available sources verbose : boolean (False) toggle verbose output .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' imgadm.sources """ ret = {} cmd = "imgadm sources -j" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode) return ret for src in salt.utils.json.loads(res["stdout"]): ret[src["url"]] = src del src["url"] if not verbose: ret = list(ret) return ret def source_delete(source): """ Delete a source source : string source url to delete .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' imgadm.source_delete https://updates.joyent.com """ ret = {} cmd = f"imgadm sources -d {source}" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode, res["stderr"]) return ret return sources(False) def source_add(source, source_type="imgapi"): """ Add a new source source : string source url to add source_trype : string (imgapi) source type, either imgapi or docker .. versionadded:: 2019.2.0 CLI Example: .. code-block:: bash salt '*' imgadm.source_add https://updates.joyent.com salt '*' imgadm.source_add https://docker.io docker """ ret = {} # NOTE: there are some undocumented deprecated source types # so we just warn instead of error on those if source_type not in ["imgapi", "docker"]: log.warning("Possible unsupported imgage source type specified!") cmd = f"imgadm sources -a {source} -t {source_type}" res = __salt__["cmd.run_all"](cmd) retcode = res["retcode"] if retcode != 0: ret["Error"] = _exit_status(retcode, res["stderr"]) return ret return sources(False)