diff --git a/Dockerfile.test b/Dockerfile.test index 961a2f83..0d8c611e 100644 --- a/Dockerfile.test +++ b/Dockerfile.test @@ -1,4 +1,4 @@ -FROM registry.fedoraproject.org/fedora:rawhide +FROM registry.fedoraproject.org/fedora:33 COPY test-packages . RUN dnf -y install $(cat test-packages) && touch /.in-container RUN useradd weldr diff --git a/docs/composer.cli.rst b/docs/composer.cli.rst index c1366a8e..4dd2e240 100644 --- a/docs/composer.cli.rst +++ b/docs/composer.cli.rst @@ -92,7 +92,6 @@ composer.cli.utilities module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/composer.rst b/docs/composer.rst index dd0c06cb..1ff06326 100644 --- a/docs/composer.rst +++ b/docs/composer.rst @@ -5,6 +5,7 @@ Subpackages ----------- .. toctree:: + :maxdepth: 4 composer.cli @@ -27,7 +28,6 @@ composer.unix\_socket module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/html/.buildinfo b/docs/html/.buildinfo index 7fc5e974..f79cfffa 100644 --- a/docs/html/.buildinfo +++ b/docs/html/.buildinfo @@ -1,4 +1,4 @@ # Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: cc96a7979dd426b55b81326d60413ee2 +config: 9b3b905a33a257ccd41a2e1f4238d37b tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/docs/html/.doctrees/composer-cli.doctree b/docs/html/.doctrees/composer-cli.doctree index 420c7698..d22943c0 100644 Binary files a/docs/html/.doctrees/composer-cli.doctree and b/docs/html/.doctrees/composer-cli.doctree differ diff --git a/docs/html/.doctrees/composer.cli.doctree b/docs/html/.doctrees/composer.cli.doctree index 2469827a..174b6a9a 100644 Binary files a/docs/html/.doctrees/composer.cli.doctree and b/docs/html/.doctrees/composer.cli.doctree differ diff --git a/docs/html/.doctrees/composer.doctree b/docs/html/.doctrees/composer.doctree index ee386c33..04cba15a 100644 Binary files a/docs/html/.doctrees/composer.doctree and b/docs/html/.doctrees/composer.doctree differ diff --git a/docs/html/.doctrees/environment.pickle b/docs/html/.doctrees/environment.pickle index b3f8e99c..2cbef633 100644 Binary files a/docs/html/.doctrees/environment.pickle and b/docs/html/.doctrees/environment.pickle differ diff --git a/docs/html/.doctrees/index.doctree b/docs/html/.doctrees/index.doctree index 6286e455..64765177 100644 Binary files a/docs/html/.doctrees/index.doctree and b/docs/html/.doctrees/index.doctree differ diff --git a/docs/html/.doctrees/intro.doctree b/docs/html/.doctrees/intro.doctree index 72b37930..695b417a 100644 Binary files a/docs/html/.doctrees/intro.doctree and b/docs/html/.doctrees/intro.doctree differ diff --git a/docs/html/.doctrees/lifted.doctree b/docs/html/.doctrees/lifted.doctree index 85b4d92f..083c02e8 100644 Binary files a/docs/html/.doctrees/lifted.doctree and b/docs/html/.doctrees/lifted.doctree differ diff --git a/docs/html/.doctrees/livemedia-creator.doctree b/docs/html/.doctrees/livemedia-creator.doctree index 68718276..a44ec5a0 100644 Binary files a/docs/html/.doctrees/livemedia-creator.doctree and b/docs/html/.doctrees/livemedia-creator.doctree differ diff --git a/docs/html/.doctrees/lorax-composer.doctree b/docs/html/.doctrees/lorax-composer.doctree index 34d603c5..8e694ef9 100644 Binary files a/docs/html/.doctrees/lorax-composer.doctree and b/docs/html/.doctrees/lorax-composer.doctree differ diff --git a/docs/html/.doctrees/lorax.doctree b/docs/html/.doctrees/lorax.doctree index 17d77e66..bc096b53 100644 Binary files a/docs/html/.doctrees/lorax.doctree and b/docs/html/.doctrees/lorax.doctree differ diff --git a/docs/html/.doctrees/mkksiso.doctree b/docs/html/.doctrees/mkksiso.doctree index cdf4f894..feb58f97 100644 Binary files a/docs/html/.doctrees/mkksiso.doctree and b/docs/html/.doctrees/mkksiso.doctree differ diff --git a/docs/html/.doctrees/modules.doctree b/docs/html/.doctrees/modules.doctree index d82a043f..25540e66 100644 Binary files a/docs/html/.doctrees/modules.doctree and b/docs/html/.doctrees/modules.doctree differ diff --git a/docs/html/.doctrees/product-images.doctree b/docs/html/.doctrees/product-images.doctree index db6e5144..23e13a77 100644 Binary files a/docs/html/.doctrees/product-images.doctree and b/docs/html/.doctrees/product-images.doctree differ diff --git a/docs/html/.doctrees/pylorax.api.doctree b/docs/html/.doctrees/pylorax.api.doctree index 89b8de61..2d2d5f94 100644 Binary files a/docs/html/.doctrees/pylorax.api.doctree and b/docs/html/.doctrees/pylorax.api.doctree differ diff --git a/docs/html/.doctrees/pylorax.doctree b/docs/html/.doctrees/pylorax.doctree index af098796..e4ed89d3 100644 Binary files a/docs/html/.doctrees/pylorax.doctree and b/docs/html/.doctrees/pylorax.doctree differ diff --git a/docs/html/_modules/composer/cli.html b/docs/html/_modules/composer/cli.html index c00c8d03..51d4c38a 100644 --- a/docs/html/_modules/composer/cli.html +++ b/docs/html/_modules/composer/cli.html @@ -8,7 +8,7 @@ - composer.cli — Lorax 33.2 documentation + composer.cli — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,14 +176,14 @@ import logging log = logging.getLogger("composer-cli") -from composer.cli.blueprints import blueprints_cmd -from composer.cli.modules import modules_cmd -from composer.cli.projects import projects_cmd -from composer.cli.compose import compose_cmd -from composer.cli.sources import sources_cmd -from composer.cli.status import status_cmd -from composer.cli.upload import upload_cmd -from composer.cli.providers import providers_cmd +from composer.cli.blueprints import blueprints_cmd +from composer.cli.modules import modules_cmd +from composer.cli.projects import projects_cmd +from composer.cli.compose import compose_cmd +from composer.cli.sources import sources_cmd +from composer.cli.status import status_cmd +from composer.cli.upload import upload_cmd +from composer.cli.providers import providers_cmd command_map = { "blueprints": blueprints_cmd, diff --git a/docs/html/_modules/composer/cli/blueprints.html b/docs/html/_modules/composer/cli/blueprints.html index 0c4d57bc..c369fa53 100644 --- a/docs/html/_modules/composer/cli/blueprints.html +++ b/docs/html/_modules/composer/cli/blueprints.html @@ -8,7 +8,7 @@ - composer.cli.blueprints — Lorax 33.2 documentation + composer.cli.blueprints — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,10 +178,10 @@ import os -from composer import http_client as client -from composer.cli.help import blueprints_help -from composer.cli.utilities import argify, frozen_toml_filename, toml_filename, handle_api_result -from composer.cli.utilities import packageNEVRA +from composer import http_client as client +from composer.cli.help import blueprints_help +from composer.cli.utilities import argify, frozen_toml_filename, toml_filename, handle_api_result +from composer.cli.utilities import packageNEVRA
[docs]def blueprints_cmd(opts): """Process blueprints commands diff --git a/docs/html/_modules/composer/cli/cmdline.html b/docs/html/_modules/composer/cli/cmdline.html index e1a038bc..15100bd0 100644 --- a/docs/html/_modules/composer/cli/cmdline.html +++ b/docs/html/_modules/composer/cli/cmdline.html @@ -8,7 +8,7 @@ - composer.cli.cmdline — Lorax 33.2 documentation + composer.cli.cmdline — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -177,8 +177,8 @@ import sys import argparse -from composer import vernum -from composer.cli.help import epilog +from composer import vernum +from composer.cli.help import epilog VERSION = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum) diff --git a/docs/html/_modules/composer/cli/compose.html b/docs/html/_modules/composer/cli/compose.html index 6f353f03..2bf6847f 100644 --- a/docs/html/_modules/composer/cli/compose.html +++ b/docs/html/_modules/composer/cli/compose.html @@ -8,7 +8,7 @@ - composer.cli.compose — Lorax 33.2 documentation + composer.cli.compose — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -158,7 +158,7 @@

Source code for composer.cli.compose

 #
-# Copyright (C) 2018  Red Hat, Inc.
+# Copyright (C) 2018-2020 Red Hat, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -176,14 +176,14 @@
 import logging
 log = logging.getLogger("composer-cli")
 
-from datetime import datetime
+from datetime import datetime
 import sys
 import json
 import toml
 
-from composer import http_client as client
-from composer.cli.help import compose_help
-from composer.cli.utilities import argify, handle_api_result, packageNEVRA
+from composer import http_client as client
+from composer.cli.help import compose_help
+from composer.cli.utilities import argify, handle_api_result, packageNEVRA, get_arg
 
 
[docs]def compose_cmd(opts): """Process compose commands @@ -194,7 +194,18 @@ :rtype: int This dispatches the compose commands to a function + + compose_cmd expects api to be passed. eg. + + {"version": 1, "backend": "lorax-composer"} + """ + result = client.get_url_json(opts.socket, "/api/status") + # Get the api version and fall back to 0 if it fails. + api_version = result.get("api", "0") + backend = result.get("backend", "unknown") + api = {"version": api_version, "backend": backend} + cmd_map = { "list": compose_list, "status": compose_status, @@ -208,6 +219,7 @@ "results": compose_results, "logs": compose_logs, "image": compose_image, + "start-ostree": compose_ostree, } if opts.args[1] == "help" or opts.args[1] == "--help": print(compose_help) @@ -216,9 +228,52 @@ log.error("Unknown compose command: %s", opts.args[1]) return 1 - return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json, opts.testmode)
+ return cmd_map[opts.args[1]](opts.socket, opts.api_version, opts.args[2:], opts.json, opts.testmode, api=api)
-
[docs]def compose_list(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def get_size(args): + """Return optional --size argument, and remaining args + + :param args: list of arguments + :type args: list of strings + :returns: (args, size) + :rtype: tuple + + - check size argument for int + - check other args for --size in wrong place + - raise error? Or just return 0? + - no size returns 0 in size + - multiply by 1024**2 to make it easier on users to specify large sizes + + """ + args, value = get_arg(args, "--size", int) + value = value * 1024**2 if value is not None else 0 + return (args, value)
+ +
[docs]def get_parent(args): + """Return optional --parent argument, and remaining args + + :param args: list of arguments + :type args: list of strings + :returns: (args, parent) + :rtype: tuple + """ + args, value = get_arg(args, "--parent") + value = value if value is not None else "" + return (args, value)
+ +
[docs]def get_ref(args): + """Return optional --ref argument, and remaining args + + :param args: list of arguments + :type args: list of strings + :returns: (args, parent) + :rtype: tuple + """ + args, value = get_arg(args, "--ref") + value = value if value is not None else "" + return (args, value)
+ +
[docs]def compose_list(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Return a simple list of compose identifiers""" states = ("running", "waiting", "finished", "failed") @@ -262,7 +317,7 @@ return 0
-
[docs]def compose_status(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_status(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Return the status of all known composes :param socket_path: Path to the Unix socket to use for API communication @@ -332,7 +387,7 @@ c["version"], c["compose_type"], image_size))
-
[docs]def compose_types(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_types(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Return information about the supported compose types :param socket_path: Path to the Unix socket to use for API communication @@ -358,7 +413,7 @@ # output a plain list of identifiers, one per line print("\n".join(t["name"] for t in result["types"] if t["enabled"]))
-
[docs]def compose_start(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_start(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Start a new compose using the selected blueprint and type :param socket_path: Path to the Unix socket to use for API communication @@ -371,9 +426,22 @@ :type show_json: bool :param testmode: Set to 1 to simulate a failed compose, set to 2 to simulate a finished one. :type testmode: int + :param api: Details about the API server, "version" and "backend" + :type api: dict - compose start <blueprint-name> <compose-type> [<image-name> <provider> <profile> | <image-name> <profile.toml>] + compose start [--size XXX] <blueprint-name> <compose-type> [<image-name> <provider> <profile> | <image-name> <profile.toml>] """ + if api == None: + log.error("Missing api version/backend") + return 1 + + # Get the optional size before checking other parameters + try: + args, size = get_size(args) + except (RuntimeError, ValueError) as e: + log.error(str(e)) + return 1 + if len(args) == 0: log.error("start is missing the blueprint name and output type") return 1 @@ -389,6 +457,12 @@ "compose_type": args[1], "branch": "master" } + if size > 0: + if api["backend"] == "lorax-composer": + log.warning("lorax-composer does not support --size, it will be ignored.") + else: + config["size"] = size + if len(args) == 4: config["upload"] = {"image_name": args[2]} # profile TOML file (maybe) @@ -421,7 +495,87 @@ return rc
-
[docs]def compose_log(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_ostree(socket_path, api_version, args, show_json=False, testmode=0, api=None): + """Start a new ostree compose using the selected blueprint and type + + :param socket_path: Path to the Unix socket to use for API communication + :type socket_path: str + :param api_version: Version of the API to talk to. eg. "0" + :type api_version: str + :param args: List of remaining arguments from the cmdline + :type args: list of str + :param show_json: Set to True to show the JSON output instead of the human readable output + :type show_json: bool + :param testmode: Set to 1 to simulate a failed compose, set to 2 to simulate a finished one. + :type testmode: int + :param api: Details about the API server, "version" and "backend" + :type api: dict + + compose start-ostree [--size XXXX] [--parent PARENT] [--ref REF] <BLUEPRINT> <TYPE> [<IMAGE-NAME> <PROFILE.TOML>] + """ + if api == None: + log.error("Missing api version/backend") + return 1 + + if api["backend"] == "lorax-composer": + log.warning("lorax-composer doesn not support start-ostree.") + return 1 + + # Get the optional size before checking other parameters + try: + args, size = get_size(args) + args, parent = get_parent(args) + args, ref = get_ref(args) + except (RuntimeError, ValueError) as e: + log.error(str(e)) + return 1 + + if len(args) == 0: + log.error("start-ostree is missing the blueprint name, output type, and ostree details") + return 1 + if len(args) == 1: + log.error("start-ostree is missing the output type") + return 1 + if len(args) == 3: + log.error("start-ostree is missing the provider TOML file") + return 1 + + config = { + "blueprint_name": args[0], + "compose_type": args[1], + "branch": "master", + "ostree": {"ref": ref, "parent": parent}, + } + if size > 0: + config["size"] = size + + if len(args) == 4: + config["upload"] = {"image_name": args[2]} + # profile TOML file (maybe) + try: + config["upload"].update(toml.load(args[3])) + except toml.TomlDecodeError as e: + log.error(str(e)) + return 1 + + if testmode: + test_url = "?test=%d" % testmode + else: + test_url = "" + api_route = client.api_url(api_version, "/compose" + test_url) + result = client.post_url_json(socket_path, api_route, json.dumps(config)) + (rc, exit_now) = handle_api_result(result, show_json) + if exit_now: + return rc + + print("Compose %s added to the queue" % result["build_id"]) + + if "upload_id" in result and result["upload_id"]: + print ("Upload %s added to the upload queue" % result["upload_id"]) + + return rc
+ +
[docs]def compose_log(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Show the last part of the compose log :param socket_path: Path to the Unix socket to use for API communication @@ -462,7 +616,7 @@ print(result) return 0
-
[docs]def compose_cancel(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_cancel(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Cancel a running compose :param socket_path: Path to the Unix socket to use for API communication @@ -488,7 +642,7 @@ result = client.delete_url_json(socket_path, api_route) return handle_api_result(result, show_json)[0]
-
[docs]def compose_delete(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_delete(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Delete a finished compose's results :param socket_path: Path to the Unix socket to use for API communication @@ -515,7 +669,7 @@ result = client.delete_url_json(socket_path, api_route) return handle_api_result(result, show_json)[0]
-
[docs]def compose_info(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_info(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Return detailed information about the compose :param socket_path: Path to the Unix socket to use for API communication @@ -569,7 +723,7 @@ return rc
-
[docs]def compose_metadata(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_metadata(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Download a tar file of the compose's metadata :param socket_path: Path to the Unix socket to use for API communication @@ -600,7 +754,7 @@ return rc
-
[docs]def compose_results(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_results(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Download a tar file of the compose's results :param socket_path: Path to the Unix socket to use for API communication @@ -632,7 +786,7 @@ return rc
-
[docs]def compose_logs(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_logs(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Download a tar of the compose's logs :param socket_path: Path to the Unix socket to use for API communication @@ -663,7 +817,7 @@ return rc
-
[docs]def compose_image(socket_path, api_version, args, show_json=False, testmode=0): +
[docs]def compose_image(socket_path, api_version, args, show_json=False, testmode=0, api=None): """Download the compose's output image :param socket_path: Path to the Unix socket to use for API communication diff --git a/docs/html/_modules/composer/cli/modules.html b/docs/html/_modules/composer/cli/modules.html index 729d7cc9..b49ae556 100644 --- a/docs/html/_modules/composer/cli/modules.html +++ b/docs/html/_modules/composer/cli/modules.html @@ -8,7 +8,7 @@ - composer.cli.modules — Lorax 33.2 documentation + composer.cli.modules — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,9 +176,9 @@ import logging log = logging.getLogger("composer-cli") -from composer import http_client as client -from composer.cli.help import modules_help -from composer.cli.utilities import handle_api_result +from composer import http_client as client +from composer.cli.help import modules_help +from composer.cli.utilities import handle_api_result
[docs]def modules_cmd(opts): """Process modules commands diff --git a/docs/html/_modules/composer/cli/projects.html b/docs/html/_modules/composer/cli/projects.html index 4f67804b..0d45ec87 100644 --- a/docs/html/_modules/composer/cli/projects.html +++ b/docs/html/_modules/composer/cli/projects.html @@ -8,7 +8,7 @@ - composer.cli.projects — Lorax 33.2 documentation + composer.cli.projects — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,9 +178,9 @@ import textwrap -from composer import http_client as client -from composer.cli.help import projects_help -from composer.cli.utilities import handle_api_result +from composer import http_client as client +from composer.cli.help import projects_help +from composer.cli.utilities import handle_api_result
[docs]def projects_cmd(opts): """Process projects commands diff --git a/docs/html/_modules/composer/cli/providers.html b/docs/html/_modules/composer/cli/providers.html index a8b575ae..ce431203 100644 --- a/docs/html/_modules/composer/cli/providers.html +++ b/docs/html/_modules/composer/cli/providers.html @@ -8,7 +8,7 @@ - composer.cli.providers — Lorax 33.2 documentation + composer.cli.providers — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,9 +180,9 @@ import toml import os -from composer import http_client as client -from composer.cli.help import providers_help -from composer.cli.utilities import handle_api_result, toml_filename +from composer import http_client as client +from composer.cli.help import providers_help +from composer.cli.utilities import handle_api_result, toml_filename
[docs]def providers_cmd(opts): """Process providers commands diff --git a/docs/html/_modules/composer/cli/sources.html b/docs/html/_modules/composer/cli/sources.html index 31762a1b..dc2ef070 100644 --- a/docs/html/_modules/composer/cli/sources.html +++ b/docs/html/_modules/composer/cli/sources.html @@ -8,7 +8,7 @@ - composer.cli.sources — Lorax 33.2 documentation + composer.cli.sources — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,9 +178,9 @@ import os -from composer import http_client as client -from composer.cli.help import sources_help -from composer.cli.utilities import argify, handle_api_result +from composer import http_client as client +from composer.cli.help import sources_help +from composer.cli.utilities import argify, handle_api_result
[docs]def sources_cmd(opts): """Process sources commands diff --git a/docs/html/_modules/composer/cli/status.html b/docs/html/_modules/composer/cli/status.html index 7a9de8ea..45005e92 100644 --- a/docs/html/_modules/composer/cli/status.html +++ b/docs/html/_modules/composer/cli/status.html @@ -8,7 +8,7 @@ - composer.cli.status — Lorax 33.2 documentation + composer.cli.status — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,9 +176,9 @@ import logging log = logging.getLogger("composer-cli") -from composer import http_client as client -from composer.cli.help import status_help -from composer.cli.utilities import handle_api_result +from composer import http_client as client +from composer.cli.help import status_help +from composer.cli.utilities import handle_api_result
[docs]def status_cmd(opts): """Process status commands diff --git a/docs/html/_modules/composer/cli/upload.html b/docs/html/_modules/composer/cli/upload.html index 139e59aa..544d7cd6 100644 --- a/docs/html/_modules/composer/cli/upload.html +++ b/docs/html/_modules/composer/cli/upload.html @@ -8,7 +8,7 @@ - composer.cli.upload — Lorax 33.2 documentation + composer.cli.upload — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,9 +180,9 @@ import toml import os -from composer import http_client as client -from composer.cli.help import upload_help -from composer.cli.utilities import handle_api_result +from composer import http_client as client +from composer.cli.help import upload_help +from composer.cli.utilities import handle_api_result
[docs]def upload_cmd(opts): """Process upload commands diff --git a/docs/html/_modules/composer/cli/utilities.html b/docs/html/_modules/composer/cli/utilities.html index a65037db..91bb3a5b 100644 --- a/docs/html/_modules/composer/cli/utilities.html +++ b/docs/html/_modules/composer/cli/utilities.html @@ -8,7 +8,7 @@ - composer.cli.utilities — Lorax 33.2 documentation + composer.cli.utilities — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -252,6 +252,34 @@ return "%s-%s:%s-%s.%s" % (pkg["name"], pkg["epoch"], pkg["version"], pkg["release"], pkg["arch"]) else: return "%s-%s-%s.%s" % (pkg["name"], pkg["version"], pkg["release"], pkg["arch"])
+ +
[docs]def get_arg(args, name, argtype=None): + """Return optional value from args, and remaining args + + :param args: list of arguments + :type args: list of strings + :param name: The argument to remove from the args list + :type name: string + :param argtype: Type to use for checking the argument value + :type argtype: type + :returns (args, value) + :rtype: tuple + + This removes the optional argument and value from the argument list, returns the new list, + and the value of the argument. + """ + try: + idx = args.index(name) + if len(args) < idx+2: + raise RuntimeError(f"{name} is missing the value") + value = args[idx+1] + except ValueError: + return (args, None) + + if argtype: + value = argtype(value) + + return (args[:idx]+args[idx+2:], value)
diff --git a/docs/html/_modules/composer/http_client.html b/docs/html/_modules/composer/http_client.html index d3935f0b..9c147bf2 100644 --- a/docs/html/_modules/composer/http_client.html +++ b/docs/html/_modules/composer/http_client.html @@ -8,7 +8,7 @@ - composer.http_client — Lorax 33.2 documentation + composer.http_client — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -177,9 +177,9 @@ import os import sys import json -from urllib.parse import urlparse, urlunparse +from urllib.parse import urlparse, urlunparse -from composer.unix_socket import UnixHTTPConnectionPool +from composer.unix_socket import UnixHTTPConnectionPool
[docs]def api_url(api_version, url): """Return the versioned path to the API route @@ -283,7 +283,7 @@ r_unlimited = http.request("GET", unlimited_url) return json.loads(r_unlimited.data.decode('utf-8'))
-
[docs]def delete_url_json(socket_path, url, timeout=120): +
[docs]def delete_url_json(socket_path, url): """Send a DELETE request to the url and return JSON response :param socket_path: Path to the Unix socket to use for API communication @@ -293,7 +293,7 @@ :returns: The json response from the server :rtype: dict """ - http = UnixHTTPConnectionPool(socket_path, timeout=timeout) + http = UnixHTTPConnectionPool(socket_path) r = http.request("DELETE", url) return json.loads(r.data.decode("utf-8"))
diff --git a/docs/html/_modules/composer/unix_socket.html b/docs/html/_modules/composer/unix_socket.html index 6a481636..a859b448 100644 --- a/docs/html/_modules/composer/unix_socket.html +++ b/docs/html/_modules/composer/unix_socket.html @@ -8,7 +8,7 @@ - composer.unix_socket — Lorax 33.2 documentation + composer.unix_socket — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -183,7 +183,7 @@ # https://github.com/docker/docker-py/blob/master/docker/transport/unixconn.py
[docs]class UnixHTTPConnection(http.client.HTTPConnection, object): - def __init__(self, socket_path, timeout=60): + def __init__(self, socket_path, timeout=60*5): """Create an HTTP connection to a unix domain socket :param socket_path: The path to the Unix domain socket @@ -193,7 +193,7 @@ self.socket_path = socket_path self.sock = None - def __del__(self): # base class does not have d'tor + def __del__(self): # base class does not have d'tor if self.sock: self.sock.close() @@ -205,13 +205,15 @@
[docs]class UnixHTTPConnectionPool(urllib3.connectionpool.HTTPConnectionPool): - def __init__(self, socket_path, timeout=60): + def __init__(self, socket_path, timeout=60*5): """Create a connection pool using a Unix domain socket :param socket_path: The path to the Unix domain socket :param timeout: Number of seconds to timeout the connection + + NOTE: retries are disabled for these connections, they are never useful """ - super(UnixHTTPConnectionPool, self).__init__('localhost', timeout=timeout) + super(UnixHTTPConnectionPool, self).__init__('localhost', timeout=timeout, retries=False) self.socket_path = socket_path def _new_conn(self): diff --git a/docs/html/_modules/index.html b/docs/html/_modules/index.html index 50cbac59..261849fb 100644 --- a/docs/html/_modules/index.html +++ b/docs/html/_modules/index.html @@ -8,7 +8,7 @@ - Overview: module code — Lorax 33.2 documentation + Overview: module code — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
diff --git a/docs/html/_modules/lifted/config.html b/docs/html/_modules/lifted/config.html index 4d96cb67..1c23ee37 100644 --- a/docs/html/_modules/lifted/config.html +++ b/docs/html/_modules/lifted/config.html @@ -8,7 +8,7 @@ - lifted.config — Lorax 33.2 documentation + lifted.config — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -171,7 +171,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from pylorax.sysutils import joinpaths +from pylorax.sysutils import joinpaths
[docs]def configure(conf): """Add lifted settings to the configuration diff --git a/docs/html/_modules/lifted/providers.html b/docs/html/_modules/lifted/providers.html index 4b2c88a2..33e84a5b 100644 --- a/docs/html/_modules/lifted/providers.html +++ b/docs/html/_modules/lifted/providers.html @@ -8,7 +8,7 @@ - lifted.providers — Lorax 33.2 documentation + lifted.providers — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -172,7 +172,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from glob import glob +from glob import glob import os import re import stat @@ -206,9 +206,9 @@ # create the settings directory if it doesn't exist os.makedirs(directory, exist_ok=True) - path = os.path.join(directory, f"{profile}.toml") + path = os.path.join(directory, f"{profile}.toml") if exists and not os.path.isfile(path): - raise RuntimeError(f'Couldn\'t find profile "{profile}"!') + raise RuntimeError(f'Couldn\'t find profile "{profile}"!') return os.path.abspath(path) @@ -238,7 +238,7 @@ with open(path) as provider_file: provider = toml.load(provider_file) except OSError as error: - raise RuntimeError(f'Couldn\'t find provider "{provider_name}"!') from error + raise RuntimeError(f'Couldn\'t find provider "{provider_name}"!') from error return provider
@@ -283,7 +283,7 @@ path = os.path.join(ucfg["providers_dir"], provider_name, "playbook.yaml") if not os.path.isfile(path): - raise RuntimeError(f'Couldn\'t find playbook for "{provider_name}"!') + raise RuntimeError(f'Couldn\'t find playbook for "{provider_name}"!') return path
@@ -319,16 +319,16 @@ settings_info = resolve_provider(ucfg, provider_name)["settings-info"] for key, value in settings.items(): if key not in settings_info: - raise ValueError(f'Received unexpected setting: "{key}"!') + raise ValueError(f'Received unexpected setting: "{key}"!') setting_type = settings_info[key]["type"] correct_type = type_map[setting_type] if not isinstance(value, correct_type): raise ValueError( - f'Expected a {correct_type} for "{key}", received a {type(value)}!' + f'Expected a {correct_type} for "{key}", received a {type(value)}!' ) if setting_type == "string" and "regex" in settings_info[key]: if not re.match(settings_info[key]["regex"], value): - raise ValueError(f'Value "{value}" is invalid for setting "{key}"!')
+ raise ValueError(f'Value "{value}" is invalid for setting "{key}"!')
[docs]def save_settings(ucfg, provider_name, profile, settings): diff --git a/docs/html/_modules/lifted/queue.html b/docs/html/_modules/lifted/queue.html index 0f217fad..9cbb714b 100644 --- a/docs/html/_modules/lifted/queue.html +++ b/docs/html/_modules/lifted/queue.html @@ -8,7 +8,7 @@ - lifted.queue — Lorax 33.2 documentation + lifted.queue — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -172,29 +172,29 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from functools import partial -from glob import glob +from functools import partial +from glob import glob import logging import multiprocessing # We use a multiprocessing Pool for uploads so that we can cancel them with a # simple SIGINT, which should bubble down to subprocesses. -from multiprocessing import Pool +from multiprocessing import Pool # multiprocessing.dummy is to threads as multiprocessing is to processes. # Since daemonic processes can't have children, we use a thread to monitor the # upload pool. -from multiprocessing.dummy import Process +from multiprocessing.dummy import Process -from operator import attrgetter +from operator import attrgetter import os import stat import time import pylorax.api.toml as toml -from lifted.upload import Upload -from lifted.providers import resolve_playbook_path, validate_settings +from lifted.upload import Upload +from lifted.providers import resolve_playbook_path, validate_settings # the maximum number of simultaneous uploads SIMULTANEOUS_UPLOADS = 1 @@ -216,7 +216,7 @@ # Make sure no path elements are present uuid = os.path.basename(uuid) - path = os.path.join(_get_queue_path(ucfg), f"{uuid}.toml") + path = os.path.join(_get_queue_path(ucfg), f"{uuid}.toml") if write and not os.path.exists(path): open(path, "a").close() if os.path.exists(path): @@ -261,10 +261,10 @@ return Upload(**toml.load(upload_file)) except FileNotFoundError as error: if not ignore_missing: - raise RuntimeError(f"Could not find upload {uuid}!") from error + raise RuntimeError(f"Could not find upload {uuid}!") from error except toml.TomlError as error: if not ignore_corrupt: - raise RuntimeError(f"Could not parse upload {uuid}!") from error
+ raise RuntimeError(f"Could not parse upload {uuid}!") from error
[docs]def get_uploads(ucfg, uuids): diff --git a/docs/html/_modules/lifted/upload.html b/docs/html/_modules/lifted/upload.html index ccc184dd..dff99e84 100644 --- a/docs/html/_modules/lifted/upload.html +++ b/docs/html/_modules/lifted/upload.html @@ -8,7 +8,7 @@ - lifted.upload — Lorax 33.2 documentation + lifted.upload — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -172,15 +172,15 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from datetime import datetime +from datetime import datetime import logging -from multiprocessing import current_process +from multiprocessing import current_process import os import signal -from uuid import uuid4 +from uuid import uuid4 -from ansible_runner.interface import run as ansible_run -from ansible_runner.exceptions import AnsibleRunnerException +from ansible_runner.interface import run as ansible_run +from ansible_runner.exceptions import AnsibleRunnerException log = logging.getLogger("lifted") @@ -190,7 +190,7 @@ class are serialized as TOML and stored in the upload queue directory, which is /var/lib/lorax/upload/queue/ by default""" - def __init__( + def __init__( self, uuid=None, provider_name=None, @@ -232,7 +232,7 @@ # Log multi-line messages as individual log lines for m in messages: log.info(m) - self.upload_log += f"{message}\n" + self.upload_log += f"{message}\n" if callback: callback(self) @@ -294,9 +294,9 @@ :type status_callback: function """ if self.is_cancellable(): - raise RuntimeError(f"Can't reset, status is {self.status}!") + raise RuntimeError(f"Can't reset, status is {self.status}!") if not self.image_path: - raise RuntimeError(f"Can't reset, no image supplied yet!") + raise RuntimeError("Can't reset, no image supplied yet!") # self.error = None self._log("Resetting state") self.set_status("READY", status_callback)
@@ -316,7 +316,7 @@ :type status_callback: function """ if not self.is_cancellable(): - raise RuntimeError(f"Can't cancel, status is already {self.status}!") + raise RuntimeError(f"Can't cancel, status is already {self.status}!") if self.upload_pid: os.kill(self.upload_pid, signal.SIGINT) self.set_status("CANCELLED", status_callback)
diff --git a/docs/html/_modules/pylorax.html b/docs/html/_modules/pylorax.html index a73c9b74..0d590437 100644 --- a/docs/html/_modules/pylorax.html +++ b/docs/html/_modules/pylorax.html @@ -8,7 +8,7 @@ - pylorax — Lorax 33.2 documentation + pylorax — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -189,22 +189,22 @@ import configparser import tempfile import locale -from subprocess import CalledProcessError +from subprocess import CalledProcessError import selinux -from glob import glob +from glob import glob -from pylorax.base import BaseLoraxClass, DataHolder +from pylorax.base import BaseLoraxClass, DataHolder import pylorax.output as output import dnf -from pylorax.sysutils import joinpaths, remove, linktree +from pylorax.sysutils import joinpaths, remove, linktree -from pylorax.treebuilder import RuntimeBuilder, TreeBuilder -from pylorax.buildstamp import BuildStamp -from pylorax.treeinfo import TreeInfo -from pylorax.discinfo import DiscInfo -from pylorax.executils import runcmd, runcmd_output +from pylorax.treebuilder import RuntimeBuilder, TreeBuilder +from pylorax.buildstamp import BuildStamp +from pylorax.treeinfo import TreeInfo +from pylorax.discinfo import DiscInfo +from pylorax.executils import runcmd, runcmd_output # get lorax version @@ -226,7 +226,7 @@ ppc64le="powerpc", arm="arm", armhfp="arm") - def __init__(self, buildarch): + def __init__(self, buildarch): super(ArchData, self).__init__() self.buildarch = buildarch self.basearch = dnf.rpm.basearch(buildarch) @@ -235,7 +235,7 @@
[docs]class Lorax(BaseLoraxClass): - def __init__(self): + def __init__(self): BaseLoraxClass.__init__(self) self._configured = False self.product = None @@ -476,14 +476,18 @@ logger.info("no BCJ filter for arch %s", self.arch.basearch) if squashfs_only: # Create an ext4 rootfs.img and compress it with squashfs - rb.create_squashfs_runtime(joinpaths(installroot,runtime), - compression=compression, compressargs=compressargs, - size=size) + rc = rb.create_squashfs_runtime(joinpaths(installroot,runtime), + compression=compression, compressargs=compressargs, + size=size) else: # Create an ext4 rootfs.img and compress it with squashfs - rb.create_ext4_runtime(joinpaths(installroot,runtime), - compression=compression, compressargs=compressargs, - size=size) + rc = rb.create_ext4_runtime(joinpaths(installroot,runtime), + compression=compression, compressargs=compressargs, + size=size) + if rc != 0: + logger.error("rootfs.img creation failed. See program.log") + sys.exit(1) + rb.finished() logger.info("preparing to build output tree and boot images") diff --git a/docs/html/_modules/pylorax/api/bisect.html b/docs/html/_modules/pylorax/api/bisect.html index 1b3b19c6..fa945218 100644 --- a/docs/html/_modules/pylorax/api/bisect.html +++ b/docs/html/_modules/pylorax/api/bisect.html @@ -8,7 +8,7 @@ - pylorax.api.bisect — Lorax 33.2 documentation + pylorax.api.bisect — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
diff --git a/docs/html/_modules/pylorax/api/checkparams.html b/docs/html/_modules/pylorax/api/checkparams.html index d3719448..d81dcc2b 100644 --- a/docs/html/_modules/pylorax/api/checkparams.html +++ b/docs/html/_modules/pylorax/api/checkparams.html @@ -8,7 +8,7 @@ - pylorax.api.checkparams — Lorax 33.2 documentation + pylorax.api.checkparams — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -177,8 +177,8 @@ import logging log = logging.getLogger("lorax-composer") -from flask import jsonify -from functools import update_wrapper +from flask import jsonify +from functools import update_wrapper # A decorator for checking the parameters provided to the API route implementing # functions. The tuples parameter is a list of tuples. Each tuple is the string diff --git a/docs/html/_modules/pylorax/api/cmdline.html b/docs/html/_modules/pylorax/api/cmdline.html index a6e0182f..5c677db4 100644 --- a/docs/html/_modules/pylorax/api/cmdline.html +++ b/docs/html/_modules/pylorax/api/cmdline.html @@ -8,7 +8,7 @@ - pylorax.api.cmdline — Lorax 33.2 documentation + pylorax.api.cmdline — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -179,7 +179,7 @@ import sys import argparse -from pylorax import vernum +from pylorax import vernum DEFAULT_USER = "root" DEFAULT_GROUP = "weldr" diff --git a/docs/html/_modules/pylorax/api/compose.html b/docs/html/_modules/pylorax/api/compose.html index ac8e1483..42917015 100644 --- a/docs/html/_modules/pylorax/api/compose.html +++ b/docs/html/_modules/pylorax/api/compose.html @@ -8,7 +8,7 @@ - pylorax.api.compose — Lorax 33.2 documentation + pylorax.api.compose — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -193,27 +193,27 @@ log = logging.getLogger("lorax-composer") import os -from glob import glob -from io import StringIO -from math import ceil +from glob import glob +from io import StringIO +from math import ceil import shutil -from uuid import uuid4 +from uuid import uuid4 # Use pykickstart to calculate disk image size -from pykickstart.parser import KickstartParser -from pykickstart.version import makeVersion +from pykickstart.parser import KickstartParser +from pykickstart.version import makeVersion -from pylorax import ArchData, find_templates, get_buildarch -from pylorax.api.gitrpm import create_gitrpm_repo -from pylorax.api.projects import projects_depsolve, projects_depsolve_with_size, dep_nevra -from pylorax.api.projects import ProjectsError -from pylorax.api.recipes import read_recipe_and_id -from pylorax.api.timestamp import TS_CREATED, write_timestamp +from pylorax import ArchData, find_templates, get_buildarch +from pylorax.api.gitrpm import create_gitrpm_repo +from pylorax.api.projects import projects_depsolve, projects_depsolve_with_size, dep_nevra +from pylorax.api.projects import ProjectsError +from pylorax.api.recipes import read_recipe_and_id +from pylorax.api.timestamp import TS_CREATED, write_timestamp import pylorax.api.toml as toml -from pylorax.base import DataHolder -from pylorax.imgutils import default_image_name -from pylorax.ltmpl import LiveTemplateRunner -from pylorax.sysutils import joinpaths, flatconfig +from pylorax.base import DataHolder +from pylorax.imgutils import default_image_name +from pylorax.ltmpl import LiveTemplateRunner +from pylorax.sysutils import joinpaths, flatconfig
[docs]def test_templates(dbo, share_dir): diff --git a/docs/html/_modules/pylorax/api/config.html b/docs/html/_modules/pylorax/api/config.html index e530bde4..eaaffe1d 100644 --- a/docs/html/_modules/pylorax/api/config.html +++ b/docs/html/_modules/pylorax/api/config.html @@ -8,7 +8,7 @@ - pylorax.api.config — Lorax 33.2 documentation + pylorax.api.config — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,7 +178,7 @@ import os import pwd -from pylorax.sysutils import joinpaths +from pylorax.sysutils import joinpaths
[docs]class ComposerConfig(configparser.ConfigParser):
[docs] def get_default(self, section, option, default): diff --git a/docs/html/_modules/pylorax/api/dnfbase.html b/docs/html/_modules/pylorax/api/dnfbase.html index 9df8a254..5fa6b8f0 100644 --- a/docs/html/_modules/pylorax/api/dnfbase.html +++ b/docs/html/_modules/pylorax/api/dnfbase.html @@ -8,7 +8,7 @@ - pylorax.api.dnfbase — Lorax 33.2 documentation + pylorax.api.dnfbase — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,14 +180,14 @@ import dnf import dnf.logging -from glob import glob +from glob import glob import os import shutil -from threading import Lock +from threading import Lock import time -from pylorax import DEFAULT_PLATFORM_ID -from pylorax.sysutils import flatconfig +from pylorax import DEFAULT_PLATFORM_ID +from pylorax.sysutils import flatconfig
[docs]class DNFLock(object): """Hold the dnf.Base object and a Lock to control access to it. @@ -195,7 +195,7 @@ self.dbo is a property that returns the dnf.Base object, but it *may* change from one call to the next if the upstream repositories have changed. """ - def __init__(self, conf, expire_secs=6*60*60): + def __init__(self, conf, expire_secs=6*60*60): self._conf = conf self._lock = Lock() self.dbo = get_base_object(self._conf) diff --git a/docs/html/_modules/pylorax/api/flask_blueprint.html b/docs/html/_modules/pylorax/api/flask_blueprint.html index c96c3613..269f9f95 100644 --- a/docs/html/_modules/pylorax/api/flask_blueprint.html +++ b/docs/html/_modules/pylorax/api/flask_blueprint.html @@ -8,7 +8,7 @@ - pylorax.api.flask_blueprint — Lorax 33.2 documentation + pylorax.api.flask_blueprint — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -192,11 +192,11 @@ and then register v1's version of `/blueprints/list` under `/api/v1` """ -from flask import Blueprint -from flask.blueprints import BlueprintSetupState +from flask import Blueprint +from flask.blueprints import BlueprintSetupState
[docs]class BlueprintSetupStateSkip(BlueprintSetupState): - def __init__(self, blueprint, app, options, first_registration, skip_rules): + def __init__(self, blueprint, app, options, first_registration, skip_rules): self._skip_rules = skip_rules super(BlueprintSetupStateSkip, self).__init__(blueprint, app, options, first_registration) @@ -205,7 +205,7 @@ super(BlueprintSetupStateSkip, self).add_url_rule(rule, endpoint, view_func, **options)
[docs]class BlueprintSkip(Blueprint): - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs): super(BlueprintSkip, self).__init__(*args, **kwargs)
[docs] def make_setup_state(self, app, options, first_registration=False): diff --git a/docs/html/_modules/pylorax/api/gitrpm.html b/docs/html/_modules/pylorax/api/gitrpm.html index 8168c277..ff0bc5a2 100644 --- a/docs/html/_modules/pylorax/api/gitrpm.html +++ b/docs/html/_modules/pylorax/api/gitrpm.html @@ -8,7 +8,7 @@ - pylorax.api.gitrpm — Lorax 33.2 documentation + pylorax.api.gitrpm — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -182,13 +182,13 @@ log = logging.getLogger("lorax-composer") import os -from rpmfluff import SimpleRpmBuild +from rpmfluff import SimpleRpmBuild import shutil import subprocess import tempfile import time -from pylorax.sysutils import joinpaths +from pylorax.sysutils import joinpaths
[docs]def get_repo_description(gitRepo): """ Return a description including the git repo and reference @@ -202,7 +202,7 @@
[docs]class GitArchiveTarball: """Create a git archive of the selected git repo and reference""" - def __init__(self, gitRepo): + def __init__(self, gitRepo): self._gitRepo = gitRepo self.sourceName = self._gitRepo["rpmname"]+".tar.xz" @@ -248,7 +248,7 @@
[docs]class GitRpmBuild(SimpleRpmBuild): """Build an rpm containing files from a git repository""" - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs): self._base_dir = None super().__init__(*args, **kwargs) diff --git a/docs/html/_modules/pylorax/api/projects.html b/docs/html/_modules/pylorax/api/projects.html index 1ddb1455..346fe545 100644 --- a/docs/html/_modules/pylorax/api/projects.html +++ b/docs/html/_modules/pylorax/api/projects.html @@ -8,7 +8,7 @@ - pylorax.api.projects — Lorax 33.2 documentation + pylorax.api.projects — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,14 +176,14 @@ import logging log = logging.getLogger("lorax-composer") -from configparser import ConfigParser +from configparser import ConfigParser import dnf -from glob import glob +from glob import glob import os import time -from pylorax.api.bisect import insort_left -from pylorax.sysutils import joinpaths +from pylorax.api.bisect import insort_left +from pylorax.sysutils import joinpaths TIME_FORMAT = "%Y-%m-%dT%H:%M:%S" diff --git a/docs/html/_modules/pylorax/api/queue.html b/docs/html/_modules/pylorax/api/queue.html index a837e55c..df792163 100644 --- a/docs/html/_modules/pylorax/api/queue.html +++ b/docs/html/_modules/pylorax/api/queue.html @@ -8,7 +8,7 @@ - pylorax.api.queue — Lorax 33.2 documentation + pylorax.api.queue — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,24 +180,24 @@ import os import grp -from glob import glob +from glob import glob import multiprocessing as mp import pwd import shutil import subprocess -from subprocess import Popen, PIPE +from subprocess import Popen, PIPE import time -from pylorax import find_templates -from pylorax.api.compose import move_compose_results -from pylorax.api.recipes import recipe_from_file -from pylorax.api.timestamp import TS_CREATED, TS_STARTED, TS_FINISHED, write_timestamp, timestamp_dict +from pylorax import find_templates +from pylorax.api.compose import move_compose_results +from pylorax.api.recipes import recipe_from_file +from pylorax.api.timestamp import TS_CREATED, TS_STARTED, TS_FINISHED, write_timestamp, timestamp_dict import pylorax.api.toml as toml -from pylorax.base import DataHolder -from pylorax.creator import run_creator -from pylorax.sysutils import joinpaths, read_tail +from pylorax.base import DataHolder +from pylorax.creator import run_creator +from pylorax.sysutils import joinpaths, read_tail -from lifted.queue import create_upload, get_uploads, ready_upload, delete_upload +from lifted.queue import create_upload, get_uploads, ready_upload, delete_upload
[docs]def check_queues(cfg): """Check to make sure the new and run queue symlinks are correct @@ -634,7 +634,7 @@ """ results_dir = joinpaths(cfg.get("composer", "lib_dir"), "results", uuid) if not os.path.isdir(results_dir): - raise RuntimeError(f'"{uuid}" is not a valid build uuid!') + raise RuntimeError(f'"{uuid}" is not a valid build uuid!') return joinpaths(results_dir, "UPLOADS")
[docs]def uuid_schedule_upload(cfg, uuid, provider_name, image_name, settings): @@ -656,7 +656,7 @@ """ status = uuid_status(cfg, uuid) if status is None: - raise RuntimeError(f'"{uuid}" is not a valid build uuid!') + raise RuntimeError(f'"{uuid}" is not a valid build uuid!') upload = create_upload(cfg["upload"], provider_name, image_name, settings) uuid_add_upload(cfg, uuid, upload.uuid) @@ -719,7 +719,7 @@ print(upload, file=uploads_file) return - raise RuntimeError(f"{upload_uuid} is not a valid upload id!")
+ raise RuntimeError(f"{upload_uuid} is not a valid upload id!")
[docs]def uuid_ready_upload(cfg, uuid, upload_uuid): """Set an upload to READY if the build is in FINISHED state @@ -736,9 +736,9 @@ """ status = uuid_status(cfg, uuid) if not status: - raise RuntimeError(f"{uuid} is not a valid build id!") + raise RuntimeError(f"{uuid} is not a valid build id!") if status["queue_status"] != "FINISHED": - raise RuntimeError(f"Build {uuid} is not finished!") + raise RuntimeError(f"Build {uuid} is not finished!") _, image_path = uuid_image(cfg, uuid) ready_upload(cfg["upload"], upload_uuid, image_path)
diff --git a/docs/html/_modules/pylorax/api/recipes.html b/docs/html/_modules/pylorax/api/recipes.html index 93f5429b..5f9bb7db 100644 --- a/docs/html/_modules/pylorax/api/recipes.html +++ b/docs/html/_modules/pylorax/api/recipes.html @@ -8,7 +8,7 @@ - pylorax.api.recipes — Lorax 33.2 documentation + pylorax.api.recipes — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,16 +176,16 @@ import gi gi.require_version("Ggit", "1.0") -from gi.repository import Ggit as Git -from gi.repository import Gio -from gi.repository import GLib +from gi.repository import Ggit as Git +from gi.repository import Gio +from gi.repository import GLib import os import semantic_version as semver -from pylorax.api.projects import dep_evra -from pylorax.base import DataHolder -from pylorax.sysutils import joinpaths +from pylorax.api.projects import dep_evra +from pylorax.base import DataHolder +from pylorax.sysutils import joinpaths import pylorax.api.toml as toml @@ -206,7 +206,7 @@ and adds a .filename property to return the recipe's filename, and a .toml() function to return the recipe as a TOML string. """ - def __init__(self, name, description, version, modules, packages, groups, customizations=None, gitrepos=None): + def __init__(self, name, description, version, modules, packages, groups, customizations=None, gitrepos=None): # Check that version is empty or semver compatible if version: semver.Version(version) @@ -347,14 +347,14 @@ new_modules, new_packages, new_groups, customizations, gitrepos)
[docs]class RecipeModule(dict): - def __init__(self, name, version): + def __init__(self, name, version): dict.__init__(self, name=name, version=version)
[docs]class RecipePackage(RecipeModule): pass
[docs]class RecipeGroup(dict): - def __init__(self, name): + def __init__(self, name): dict.__init__(self, name=name)
[docs]def NewRecipeGit(toml_dict): @@ -401,7 +401,7 @@ toml_dict.get("destination"))
[docs]class RecipeGit(dict): - def __init__(self, rpmname, rpmversion, rpmrelease, summary, repo, ref, destination): + def __init__(self, rpmname, rpmversion, rpmrelease, summary, repo, ref, destination): dict.__init__(self, rpmname=rpmname, rpmversion=rpmversion, rpmrelease=rpmrelease, summary=summary, repo=repo, ref=ref, destination=destination)
@@ -1121,7 +1121,7 @@ return None
[docs]class CommitDetails(DataHolder): - def __init__(self, commit, timestamp, message, revision=None): + def __init__(self, commit, timestamp, message, revision=None): DataHolder.__init__(self, commit = commit, timestamp = timestamp, diff --git a/docs/html/_modules/pylorax/api/server.html b/docs/html/_modules/pylorax/api/server.html index 1b35126d..f71cf1b8 100644 --- a/docs/html/_modules/pylorax/api/server.html +++ b/docs/html/_modules/pylorax/api/server.html @@ -8,7 +8,7 @@ - pylorax.api.server — Lorax 33.2 documentation + pylorax.api.server — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,17 +176,17 @@ import logging log = logging.getLogger("lorax-composer") -from collections import namedtuple -from flask import Flask, jsonify, redirect, send_from_directory -from glob import glob +from collections import namedtuple +from flask import Flask, jsonify, redirect, send_from_directory +from glob import glob import os import werkzeug -from pylorax import vernum -from pylorax.api.errors import HTTP_ERROR -from pylorax.api.v0 import v0_api -from pylorax.api.v1 import v1_api -from pylorax.sysutils import joinpaths +from pylorax import vernum +from pylorax.api.errors import HTTP_ERROR +from pylorax.api.v0 import v0_api +from pylorax.api.v1 import v1_api +from pylorax.sysutils import joinpaths GitLock = namedtuple("GitLock", ["repo", "lock", "dir"]) diff --git a/docs/html/_modules/pylorax/api/timestamp.html b/docs/html/_modules/pylorax/api/timestamp.html index e020513b..2d035d26 100644 --- a/docs/html/_modules/pylorax/api/timestamp.html +++ b/docs/html/_modules/pylorax/api/timestamp.html @@ -8,7 +8,7 @@ - pylorax.api.timestamp — Lorax 33.2 documentation + pylorax.api.timestamp — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -176,7 +176,7 @@ import time -from pylorax.sysutils import joinpaths +from pylorax.sysutils import joinpaths import pylorax.api.toml as toml TS_CREATED = "created" diff --git a/docs/html/_modules/pylorax/api/toml.html b/docs/html/_modules/pylorax/api/toml.html index 3f282092..b41b7c7e 100644 --- a/docs/html/_modules/pylorax/api/toml.html +++ b/docs/html/_modules/pylorax/api/toml.html @@ -8,7 +8,7 @@ - pylorax.api.toml — Lorax 33.2 documentation + pylorax.api.toml — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
diff --git a/docs/html/_modules/pylorax/api/utils.html b/docs/html/_modules/pylorax/api/utils.html index d08d79b3..a4cbb4de 100644 --- a/docs/html/_modules/pylorax/api/utils.html +++ b/docs/html/_modules/pylorax/api/utils.html @@ -8,7 +8,7 @@ - pylorax.api.utils — Lorax 33.2 documentation + pylorax.api.utils — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -174,7 +174,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. """ API utility functions """ -from pylorax.api.recipes import RecipeError, RecipeFileError, read_recipe_commit +from pylorax.api.recipes import RecipeError, RecipeFileError, read_recipe_commit
[docs]def take_limits(iterable, offset, limit): """ Apply offset and limit to an iterable object diff --git a/docs/html/_modules/pylorax/api/v0.html b/docs/html/_modules/pylorax/api/v0.html index f45e7c42..7b6e4512 100644 --- a/docs/html/_modules/pylorax/api/v0.html +++ b/docs/html/_modules/pylorax/api/v0.html @@ -8,7 +8,7 @@ - pylorax.api.v0 — Lorax 33.2 documentation + pylorax.api.v0 — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -211,26 +211,26 @@ log = logging.getLogger("lorax-composer") import os -from flask import jsonify, request, Response, send_file -from flask import current_app as api +from flask import jsonify, request, Response, send_file +from flask import current_app as api -from pylorax.sysutils import joinpaths -from pylorax.api.checkparams import checkparams -from pylorax.api.compose import start_build, compose_types -from pylorax.api.errors import * # pylint: disable=wildcard-import,unused-wildcard-import -from pylorax.api.flask_blueprint import BlueprintSkip -from pylorax.api.projects import projects_list, projects_info, projects_depsolve -from pylorax.api.projects import modules_list, modules_info, ProjectsError, repo_to_source -from pylorax.api.projects import get_repo_sources, delete_repo_source, new_repo_source -from pylorax.api.queue import queue_status, build_status, uuid_delete, uuid_status, uuid_info -from pylorax.api.queue import uuid_tar, uuid_image, uuid_cancel, uuid_log -from pylorax.api.recipes import list_branch_files, read_recipe_commit, recipe_filename, list_commits -from pylorax.api.recipes import recipe_from_dict, recipe_from_toml, commit_recipe, delete_recipe, revert_recipe -from pylorax.api.recipes import tag_recipe_commit, recipe_diff, RecipeFileError -from pylorax.api.regexes import VALID_API_STRING, VALID_BLUEPRINT_NAME +from pylorax.sysutils import joinpaths +from pylorax.api.checkparams import checkparams +from pylorax.api.compose import start_build, compose_types +from pylorax.api.errors import * # pylint: disable=wildcard-import,unused-wildcard-import +from pylorax.api.flask_blueprint import BlueprintSkip +from pylorax.api.projects import projects_list, projects_info, projects_depsolve +from pylorax.api.projects import modules_list, modules_info, ProjectsError, repo_to_source +from pylorax.api.projects import get_repo_sources, delete_repo_source, new_repo_source +from pylorax.api.queue import queue_status, build_status, uuid_delete, uuid_status, uuid_info +from pylorax.api.queue import uuid_tar, uuid_image, uuid_cancel, uuid_log +from pylorax.api.recipes import list_branch_files, read_recipe_commit, recipe_filename, list_commits +from pylorax.api.recipes import recipe_from_dict, recipe_from_toml, commit_recipe, delete_recipe, revert_recipe +from pylorax.api.recipes import tag_recipe_commit, recipe_diff, RecipeFileError +from pylorax.api.regexes import VALID_API_STRING, VALID_BLUEPRINT_NAME import pylorax.api.toml as toml -from pylorax.api.utils import take_limits, blueprint_exists -from pylorax.api.workspace import workspace_read, workspace_write, workspace_delete +from pylorax.api.utils import take_limits, blueprint_exists +from pylorax.api.workspace import workspace_read, workspace_write, workspace_delete, workspace_exists # The API functions don't actually get called by any code here # pylint: disable=unused-variable @@ -640,6 +640,9 @@ try: with api.config["GITLOCK"].lock: + if not workspace_exists(api.config["GITLOCK"].repo, branch, blueprint_name): + raise Exception("Unknown blueprint: %s" % blueprint_name) + workspace_delete(api.config["GITLOCK"].repo, branch, blueprint_name) except Exception as e: log.error("(v0_blueprints_delete_workspace) %s", str(e)) @@ -666,6 +669,9 @@ if VALID_BLUEPRINT_NAME.match(blueprint_name) is None: return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + if VALID_BLUEPRINT_NAME.match(commit) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + branch = request.args.get("branch", "master") if VALID_API_STRING.match(branch) is None: return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in branch argument"}]), 400 @@ -1802,6 +1808,11 @@ status = request.args.get("status", None) compose_type = request.args.get("type", None) + # Check the arguments for invalid characters + for a in [blueprint, status, compose_type]: + if a is not None and VALID_API_STRING.match(a) is None: + return jsonify(status=False, errors=[{"id": INVALID_CHARS, "msg": "Invalid characters in API path"}]), 400 + results = [] errors = [] diff --git a/docs/html/_modules/pylorax/api/v1.html b/docs/html/_modules/pylorax/api/v1.html index 20b8aa96..87c82771 100644 --- a/docs/html/_modules/pylorax/api/v1.html +++ b/docs/html/_modules/pylorax/api/v1.html @@ -8,7 +8,7 @@ - pylorax.api.v1 — Lorax 33.2 documentation + pylorax.api.v1 — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -179,25 +179,25 @@ import logging log = logging.getLogger("lorax-composer") -from flask import jsonify, request -from flask import current_app as api +from flask import jsonify, request +from flask import current_app as api -from lifted.queue import get_upload, reset_upload, cancel_upload, delete_upload -from lifted.providers import list_providers, resolve_provider, load_profiles, validate_settings, save_settings -from lifted.providers import load_settings, delete_profile -from pylorax.api.checkparams import checkparams -from pylorax.api.compose import start_build -from pylorax.api.errors import BAD_COMPOSE_TYPE, BUILD_FAILED, INVALID_CHARS, MISSING_POST, PROJECTS_ERROR -from pylorax.api.errors import SYSTEM_SOURCE, UNKNOWN_BLUEPRINT, UNKNOWN_SOURCE, UNKNOWN_UUID, UPLOAD_ERROR -from pylorax.api.errors import COMPOSE_ERROR -from pylorax.api.flask_blueprint import BlueprintSkip -from pylorax.api.queue import queue_status, build_status, uuid_status, uuid_schedule_upload, uuid_remove_upload -from pylorax.api.queue import uuid_info -from pylorax.api.projects import get_repo_sources, repo_to_source -from pylorax.api.projects import new_repo_source -from pylorax.api.regexes import VALID_API_STRING, VALID_BLUEPRINT_NAME +from lifted.queue import get_upload, reset_upload, cancel_upload, delete_upload +from lifted.providers import list_providers, resolve_provider, load_profiles, validate_settings, save_settings +from lifted.providers import load_settings, delete_profile +from pylorax.api.checkparams import checkparams +from pylorax.api.compose import start_build +from pylorax.api.errors import BAD_COMPOSE_TYPE, BUILD_FAILED, INVALID_CHARS, MISSING_POST, PROJECTS_ERROR +from pylorax.api.errors import SYSTEM_SOURCE, UNKNOWN_BLUEPRINT, UNKNOWN_SOURCE, UNKNOWN_UUID, UPLOAD_ERROR +from pylorax.api.errors import COMPOSE_ERROR +from pylorax.api.flask_blueprint import BlueprintSkip +from pylorax.api.queue import queue_status, build_status, uuid_status, uuid_schedule_upload, uuid_remove_upload +from pylorax.api.queue import uuid_info +from pylorax.api.projects import get_repo_sources, repo_to_source +from pylorax.api.projects import new_repo_source +from pylorax.api.regexes import VALID_API_STRING, VALID_BLUEPRINT_NAME import pylorax.api.toml as toml -from pylorax.api.utils import blueprint_exists +from pylorax.api.utils import blueprint_exists # Create the v1 routes Blueprint with skip_routes support @@ -451,11 +451,11 @@ provider_name = compose["upload"]["provider"] settings = compose["upload"]["settings"] except KeyError as e: - errors.append({"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'}) + errors.append({"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'}) try: provider = resolve_provider(api.config["COMPOSER_CFG"]["upload"], provider_name) if "supported_types" in provider and compose_type not in provider["supported_types"]: - raise RuntimeError(f'Type "{compose_type}" is not supported by provider "{provider_name}"!') + raise RuntimeError(f'Type "{compose_type}" is not supported by provider "{provider_name}"!') validate_settings(api.config["COMPOSER_CFG"]["upload"], provider_name, settings, image_name) except Exception as e: errors.append({"id": UPLOAD_ERROR, "msg": str(e)}) @@ -887,14 +887,14 @@ else: settings = parsed["settings"] except KeyError as e: - error = {"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'} + error = {"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'} return jsonify(status=False, errors=[error]), 400 try: compose_type = uuid_status(api.config["COMPOSER_CFG"], compose_uuid)["compose_type"] provider = resolve_provider(api.config["COMPOSER_CFG"]["upload"], provider_name) if "supported_types" in provider and compose_type not in provider["supported_types"]: raise RuntimeError( - f'Type "{compose_type}" is not supported by provider "{provider_name}"!' + f'Type "{compose_type}" is not supported by provider "{provider_name}"!' ) except Exception as e: return jsonify(status=False, errors=[{"id": UPLOAD_ERROR, "msg": str(e)}]), 400 @@ -1166,7 +1166,7 @@ profile = parsed["profile"] settings = parsed["settings"] except KeyError as e: - error = {"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'} + error = {"id": UPLOAD_ERROR, "msg": f'Missing parameter {str(e)}!'} return jsonify(status=False, errors=[error]), 400 try: save_settings(api.config["COMPOSER_CFG"]["upload"], provider_name, profile, settings) diff --git a/docs/html/_modules/pylorax/api/workspace.html b/docs/html/_modules/pylorax/api/workspace.html index 8d2ae643..366be10c 100644 --- a/docs/html/_modules/pylorax/api/workspace.html +++ b/docs/html/_modules/pylorax/api/workspace.html @@ -8,7 +8,7 @@ - pylorax.api.workspace — Lorax 33.2 documentation + pylorax.api.workspace — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -175,8 +175,8 @@ # import os -from pylorax.api.recipes import recipe_filename, recipe_from_toml, RecipeFileError -from pylorax.sysutils import joinpaths +from pylorax.api.recipes import recipe_filename, recipe_from_toml, RecipeFileError +from pylorax.sysutils import joinpaths
[docs]def workspace_dir(repo, branch): @@ -240,6 +240,37 @@ open(filename, 'wb').write(recipe.toml().encode("UTF-8"))
+
[docs]def workspace_filename(repo, branch, recipe_name): + """Return the path and filename of the workspace recipe + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: The name of the recipe + :type recipe_name: str + :returns: workspace recipe path and filename + :rtype: str + """ + ws_dir = workspace_dir(repo, branch) + return joinpaths(ws_dir, recipe_filename(recipe_name))
+ + +
[docs]def workspace_exists(repo, branch, recipe_name): + """Return true of the workspace recipe exists + + :param repo: Open repository + :type repo: Git.Repository + :param branch: Branch name + :type branch: str + :param recipe_name: The name of the recipe + :type recipe_name: str + :returns: True if the file exists + :rtype: bool + """ + return os.path.exists(workspace_filename(repo, branch, recipe_name))
+ +
[docs]def workspace_delete(repo, branch, recipe_name): """Delete the recipe from the workspace @@ -252,8 +283,7 @@ :returns: None :raises: IO related errors """ - ws_dir = workspace_dir(repo, branch) - filename = joinpaths(ws_dir, recipe_filename(recipe_name)) + filename = workspace_filename(repo, branch, recipe_name) if os.path.exists(filename): os.unlink(filename)
diff --git a/docs/html/_modules/pylorax/base.html b/docs/html/_modules/pylorax/base.html index 785a954a..dd6f36b9 100644 --- a/docs/html/_modules/pylorax/base.html +++ b/docs/html/_modules/pylorax/base.html @@ -8,7 +8,7 @@ - pylorax.base — Lorax 33.2 documentation + pylorax.base — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,7 +178,7 @@ # Red Hat Author(s): Martin Gracik <mgracik@redhat.com> # -from abc import ABCMeta, abstractmethod +from abc import ABCMeta, abstractmethod import sys import pylorax.output as output @@ -186,7 +186,7 @@
[docs]class BaseLoraxClass(object, metaclass=ABCMeta): @abstractmethod - def __init__(self): + def __init__(self): self.output = output.LoraxOutput()
[docs] def pcritical(self, msg, fobj=sys.stdout): @@ -207,19 +207,19 @@
[docs]class DataHolder(dict): - def __init__(self, **kwargs): + def __init__(self, **kwargs): dict.__init__(self) for attr, value in kwargs.items(): self[attr] = value - def __getattr__(self, attr): + def __getattr__(self, attr): if attr in self: return self[attr] else: raise AttributeError - def __setattr__(self, attr, value): + def __setattr__(self, attr, value): self[attr] = value
[docs] def copy(self): diff --git a/docs/html/_modules/pylorax/buildstamp.html b/docs/html/_modules/pylorax/buildstamp.html index 344923be..e9dfc42e 100644 --- a/docs/html/_modules/pylorax/buildstamp.html +++ b/docs/html/_modules/pylorax/buildstamp.html @@ -8,7 +8,7 @@ - pylorax.buildstamp — Lorax 33.2 documentation + pylorax.buildstamp — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -187,7 +187,7 @@
[docs]class BuildStamp(object): - def __init__(self, product, version, bugurl, isfinal, buildarch, variant=""): + def __init__(self, product, version, bugurl, isfinal, buildarch, variant=""): self.product = product self.version = version self.bugurl = bugurl diff --git a/docs/html/_modules/pylorax/cmdline.html b/docs/html/_modules/pylorax/cmdline.html index fc18e7e8..6e52388d 100644 --- a/docs/html/_modules/pylorax/cmdline.html +++ b/docs/html/_modules/pylorax/cmdline.html @@ -8,7 +8,7 @@ - pylorax.cmdline — Lorax 33.2 documentation + pylorax.cmdline — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -181,7 +181,7 @@ import sys import argparse -from pylorax import vernum +from pylorax import vernum version = "{0}-{1}".format(os.path.basename(sys.argv[0]), vernum) diff --git a/docs/html/_modules/pylorax/creator.html b/docs/html/_modules/pylorax/creator.html index 18269b49..bc25fdde 100644 --- a/docs/html/_modules/pylorax/creator.html +++ b/docs/html/_modules/pylorax/creator.html @@ -8,7 +8,7 @@ - pylorax.creator — Lorax 33.2 documentation + pylorax.creator — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -184,26 +184,26 @@ import glob # Use Mako templates for appliance builder descriptions -from mako.template import Template -from mako.exceptions import text_error_template +from mako.template import Template +from mako.exceptions import text_error_template # Use pykickstart to calculate disk image size -from pykickstart.parser import KickstartParser -from pykickstart.constants import KS_SHUTDOWN -from pykickstart.version import makeVersion +from pykickstart.parser import KickstartParser +from pykickstart.constants import KS_SHUTDOWN +from pykickstart.version import makeVersion # Use the Lorax treebuilder branch for iso creation -from pylorax import ArchData -from pylorax.base import DataHolder -from pylorax.executils import execWithRedirect, runcmd -from pylorax.imgutils import PartitionMount -from pylorax.imgutils import mount, umount, Mount -from pylorax.imgutils import mksquashfs, mkrootfsimg -from pylorax.imgutils import copytree -from pylorax.installer import novirt_install, virt_install, InstallError -from pylorax.treebuilder import TreeBuilder, RuntimeBuilder -from pylorax.treebuilder import findkernels -from pylorax.sysutils import joinpaths, remove +from pylorax import ArchData +from pylorax.base import DataHolder +from pylorax.executils import execWithRedirect, runcmd +from pylorax.imgutils import PartitionMount +from pylorax.imgutils import mount, umount, Mount +from pylorax.imgutils import mksquashfs, mkrootfsimg +from pylorax.imgutils import copytree +from pylorax.installer import novirt_install, virt_install, InstallError +from pylorax.treebuilder import TreeBuilder, RuntimeBuilder +from pylorax.treebuilder import findkernels +from pylorax.sysutils import joinpaths, remove # Default parameters for rebuilding initramfs, override with --dracut-arg or --dracut-conf @@ -220,7 +220,7 @@ templates, so the the installroot config value is the important part of this. Everything else should be a nop. """ - def __init__(self, conf): + def __init__(self, conf): self.conf = conf
[docs] def reset(self): @@ -364,6 +364,8 @@ :param str mount_dir: Directory tree to compress :param str work_dir: Output compressed image to work_dir+images/install.img :param int size: Size of disk image, in GiB + :returns: rc of squashfs creation + :rtype: int """ kernel_arch = get_arch(mount_dir) @@ -380,12 +382,12 @@ if opts.squashfs_only: log.info("Creating a squashfs only runtime") - rb.create_squashfs_runtime(joinpaths(work_dir, RUNTIME), size=size, - compression=compression, compressargs=compressargs) + return rb.create_squashfs_runtime(joinpaths(work_dir, RUNTIME), size=size, + compression=compression, compressargs=compressargs) else: log.info("Creating a squashfs+ext4 runtime") - rb.create_ext4_runtime(joinpaths(work_dir, RUNTIME), size=size, - compression=compression, compressargs=compressargs)
+ return rb.create_ext4_runtime(joinpaths(work_dir, RUNTIME), size=size, + compression=compression, compressargs=compressargs)
[docs]def rebuild_initrds_for_live(opts, sys_root_dir, results_dir): @@ -412,9 +414,6 @@ if not kernels: raise Exception("No initrds found, cannot rebuild_initrds") - # Hush some dracut warnings. TODO: bind-mount proc in place? - open(joinpaths(sys_root_dir,"/proc/modules"),"w") - if opts.ostree: # Dracut assumes to have some dirs in disk image # /var/tmp for temp files @@ -442,16 +441,15 @@ # Construct an initrd from the kernel name outfile = os.path.basename(kernel.path.replace("vmlinuz-", "initrd-") + ".img") log.info("rebuilding %s", outfile) + log.info("dracut warnings about /proc are safe to ignore") kver = kernel.version - cmd = dracut + ["/results/"+outfile, kver] runcmd(cmd, root=sys_root_dir) shutil.copy2(joinpaths(sys_root_dir, kernel.path), results_dir) umount(joinpaths(sys_root_dir, "var/tmp"), delete=False) - umount(joinpaths(sys_root_dir, "results"), delete=False) - os.unlink(joinpaths(sys_root_dir,"/proc/modules"))
+ umount(joinpaths(sys_root_dir, "results"), delete=False)
[docs]def create_pxe_config(template, images_dir, live_image_name, add_args = None): """ @@ -732,7 +730,10 @@ add_pxe_args = [] live_image_name = "live-rootfs.squashfs.img" compression, compressargs = squashfs_args(opts) - mksquashfs(squashfs_root_dir, joinpaths(work_dir, live_image_name), compression, compressargs) + rc = mksquashfs(squashfs_root_dir, joinpaths(work_dir, live_image_name), compression, compressargs) + if rc != 0: + log.error("mksquashfs failed to create %s", live_image_name) + return None log.info("Rebuilding initramfs for live") with Mount(rootfs_img, opts="loop") as mnt_dir: @@ -850,9 +851,10 @@ # Create iso from a filesystem image disk_img = opts.fs_image or disk_img with Mount(disk_img, opts="loop") as mount_dir: - # TODO check rc - make_runtime(opts, mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) - + rc = make_runtime(opts, mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) + if rc != 0: + log.error("make_runtime failed with rc = %d. See program.log", rc) + raise RuntimeError("make_runtime failed with rc = %d" % rc) if cancel_func and cancel_func(): raise RuntimeError("ISO creation canceled") @@ -862,7 +864,10 @@ disk_img = opts.disk_image or disk_img with PartitionMount(disk_img) as img_mount: if img_mount and img_mount.mount_dir: - make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) + rc = make_runtime(opts, img_mount.mount_dir, work_dir, calculate_disk_size(opts, ks)/1024.0) + if rc != 0: + log.error("make_runtime failed with rc = %d. See program.log", rc) + raise RuntimeError("make_runtime failed with rc = %d" % rc) result_dir = make_livecd(opts, img_mount.mount_dir, work_dir) # --iso-only removes the extra build artifacts, keeping only the boot.iso diff --git a/docs/html/_modules/pylorax/decorators.html b/docs/html/_modules/pylorax/decorators.html index 7e63f1a7..062c3392 100644 --- a/docs/html/_modules/pylorax/decorators.html +++ b/docs/html/_modules/pylorax/decorators.html @@ -8,7 +8,7 @@ - pylorax.decorators — Lorax 33.2 documentation + pylorax.decorators — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
diff --git a/docs/html/_modules/pylorax/discinfo.html b/docs/html/_modules/pylorax/discinfo.html index d071dffa..c006b79e 100644 --- a/docs/html/_modules/pylorax/discinfo.html +++ b/docs/html/_modules/pylorax/discinfo.html @@ -8,7 +8,7 @@ - pylorax.discinfo — Lorax 33.2 documentation + pylorax.discinfo — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -187,7 +187,7 @@
[docs]class DiscInfo(object): - def __init__(self, release, basearch): + def __init__(self, release, basearch): self.release = release self.basearch = basearch diff --git a/docs/html/_modules/pylorax/dnfbase.html b/docs/html/_modules/pylorax/dnfbase.html index 9ba1207e..23c76d66 100644 --- a/docs/html/_modules/pylorax/dnfbase.html +++ b/docs/html/_modules/pylorax/dnfbase.html @@ -8,7 +8,7 @@ - pylorax.dnfbase — Lorax 33.2 documentation + pylorax.dnfbase — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -179,8 +179,8 @@ import os import shutil -from pylorax import DEFAULT_PLATFORM_ID -from pylorax.sysutils import flatconfig +from pylorax import DEFAULT_PLATFORM_ID +from pylorax.sysutils import flatconfig
[docs]def get_dnf_base_object(installroot, sources, mirrorlists=None, repos=None, enablerepos=None, disablerepos=None, diff --git a/docs/html/_modules/pylorax/dnfhelper.html b/docs/html/_modules/pylorax/dnfhelper.html index d5954848..8e1b8917 100644 --- a/docs/html/_modules/pylorax/dnfhelper.html +++ b/docs/html/_modules/pylorax/dnfhelper.html @@ -8,7 +8,7 @@ - pylorax.dnfhelper — Lorax 33.2 documentation + pylorax.dnfhelper — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -201,7 +201,7 @@
[docs]class LoraxDownloadCallback(dnf.callback.DownloadProgress): - def __init__(self): + def __init__(self): self.downloads = collections.defaultdict(int) self.last_time = time.time() self.total_files = 0 @@ -248,7 +248,7 @@
[docs]class LoraxRpmCallback(dnf.callback.TransactionProgress): - def __init__(self): + def __init__(self): super(LoraxRpmCallback, self).__init__() self._last_ts = None diff --git a/docs/html/_modules/pylorax/executils.html b/docs/html/_modules/pylorax/executils.html index 55a156c6..5e9ce93a 100644 --- a/docs/html/_modules/pylorax/executils.html +++ b/docs/html/_modules/pylorax/executils.html @@ -8,7 +8,7 @@ - pylorax.executils — Lorax 33.2 documentation + pylorax.executils — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -179,7 +179,7 @@ import os import subprocess -from subprocess import TimeoutExpired +from subprocess import TimeoutExpired import signal import logging @@ -187,7 +187,7 @@ program_log = logging.getLogger("program") # pylint: disable=not-context-manager -from threading import Lock +from threading import Lock program_log_lock = Lock() _child_env = {} @@ -211,7 +211,7 @@ return env
[docs]class ExecProduct(object): - def __init__(self, rc, stdout, stderr): + def __init__(self, rc, stdout, stderr): self.rc = rc self.stdout = stdout self.stderr = stderr
@@ -443,15 +443,15 @@ up the process when the output is no longer needed. """ - def __init__(self, proc, argv, callback): + def __init__(self, proc, argv, callback): self._proc = proc self._argv = argv self._callback = callback - def __iter__(self): + def __iter__(self): return self - def __del__(self): + def __del__(self): # See if the process is still running if self._proc.poll() is None: # Stop the process and ignore any problems that might arise @@ -460,7 +460,7 @@ except OSError: pass - def __next__(self): + def __next__(self): # Read the next line, blocking if a line is not yet available line = self._proc.stdout.readline().decode("utf-8") if line == '' or not self._callback(self._proc): diff --git a/docs/html/_modules/pylorax/imgutils.html b/docs/html/_modules/pylorax/imgutils.html index 3954e017..02742d08 100644 --- a/docs/html/_modules/pylorax/imgutils.html +++ b/docs/html/_modules/pylorax/imgutils.html @@ -8,7 +8,7 @@ - pylorax.imgutils — Lorax 33.2 documentation + pylorax.imgutils — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,18 +180,18 @@ logger = logging.getLogger("pylorax.imgutils") import os, tempfile -from os.path import join, dirname -from subprocess import Popen, PIPE, CalledProcessError +from os.path import join, dirname +from subprocess import Popen, PIPE, CalledProcessError import sys import time import traceback import multiprocessing -from time import sleep +from time import sleep import shutil -from pylorax.sysutils import cpfile -from pylorax.executils import execWithRedirect, execWithCapture -from pylorax.executils import runcmd, runcmd_output +from pylorax.sysutils import cpfile +from pylorax.executils import execWithRedirect, execWithCapture +from pylorax.executils import runcmd, runcmd_output ######## Functions for making container images (cpio, tar, squashfs) ########## @@ -496,34 +496,34 @@ ######## Execution contexts - use with the 'with' statement ##############
[docs]class LoopDev(object): - def __init__(self, filename, size=None): + def __init__(self, filename, size=None): self.loopdev = None self.filename = filename if size: mksparse(self.filename, size) - def __enter__(self): + def __enter__(self): self.loopdev = loop_attach(self.filename) return self.loopdev - def __exit__(self, exc_type, exc_value, tracebk): + def __exit__(self, exc_type, exc_value, tracebk): loop_detach(self.loopdev)
[docs]class DMDev(object): - def __init__(self, dev, size, name=None): + def __init__(self, dev, size, name=None): self.mapperdev = None (self.dev, self.size, self.name) = (dev, size, name) - def __enter__(self): + def __enter__(self): self.mapperdev = dm_attach(self.dev, self.size, self.name) return self.mapperdev - def __exit__(self, exc_type, exc_value, tracebk): + def __exit__(self, exc_type, exc_value, tracebk): dm_detach(self.mapperdev)
[docs]class Mount(object): - def __init__(self, dev, opts="", mnt=None): + def __init__(self, dev, opts="", mnt=None): (self.dev, self.opts, self.mnt) = (dev, opts, mnt) - def __enter__(self): + def __enter__(self): self.mnt = mount(self.dev, self.opts, self.mnt) return self.mnt - def __exit__(self, exc_type, exc_value, tracebk): + def __exit__(self, exc_type, exc_value, tracebk): umount(self.mnt)
[docs]def kpartx_disk_img(disk_img): @@ -553,7 +553,7 @@
[docs]class PartitionMount(object): """ Mount a partitioned image file using kpartx """ - def __init__(self, disk_img, mount_ok=None, submount=None): + def __init__(self, disk_img, mount_ok=None, submount=None): """ :param str disk_img: The full path to a partitioned disk image :param mount_ok: A function that is passed the mount point and @@ -585,7 +585,7 @@ # list of (deviceName, sizeInBytes) self.loop_devices = kpartx_disk_img(self.disk_img) - def __enter__(self): + def __enter__(self): # Mount the device selected by mount_ok, if possible self.temp_dir = tempfile.mkdtemp() if self.submount: @@ -612,7 +612,7 @@ self.temp_dir = None return self - def __exit__(self, exc_type, exc_value, tracebk): + def __exit__(self, exc_type, exc_value, tracebk): if self.temp_dir: umount(self.mount_dir) shutil.rmtree(self.temp_dir) diff --git a/docs/html/_modules/pylorax/installer.html b/docs/html/_modules/pylorax/installer.html index b19e5952..6fb2c1d4 100644 --- a/docs/html/_modules/pylorax/installer.html +++ b/docs/html/_modules/pylorax/installer.html @@ -8,7 +8,7 @@ - pylorax.installer — Lorax 33.2 documentation + pylorax.installer — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -178,7 +178,7 @@ import glob import json -from math import ceil +from math import ceil import os import subprocess import shutil @@ -186,14 +186,14 @@ import tempfile # Use the Lorax treebuilder branch for iso creation -from pylorax.executils import execWithRedirect, execReadlines -from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach -from pylorax.imgutils import get_loop_name, dm_detach, mount, umount -from pylorax.imgutils import mkqemu_img, mktar, mkcpio, mkfsimage_from_disk -from pylorax.monitor import LogMonitor -from pylorax.mount import IsoMountpoint -from pylorax.sysutils import joinpaths -from pylorax.treebuilder import udev_escape +from pylorax.executils import execWithRedirect, execReadlines +from pylorax.imgutils import PartitionMount, mksparse, mkext4img, loop_detach +from pylorax.imgutils import get_loop_name, dm_detach, mount, umount +from pylorax.imgutils import mkqemu_img, mktar, mkcpio, mkfsimage_from_disk +from pylorax.monitor import LogMonitor +from pylorax.mount import IsoMountpoint +from pylorax.sysutils import joinpaths +from pylorax.treebuilder import udev_escape ROOT_PATH = "/mnt/sysimage/" @@ -302,7 +302,7 @@ "ppc64le": "qemu-system-ppc64" } - def __init__(self, opts, iso, ks_paths, disk_img, img_size=2048, + def __init__(self, opts, iso, ks_paths, disk_img, img_size=2048, kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, cancel_func=None, virtio_host="127.0.0.1", virtio_port=6080, image_type=None, boot_uefi=False, ovmf_path=None): diff --git a/docs/html/_modules/pylorax/ltmpl.html b/docs/html/_modules/pylorax/ltmpl.html index 18a669af..afb74433 100644 --- a/docs/html/_modules/pylorax/ltmpl.html +++ b/docs/html/_modules/pylorax/ltmpl.html @@ -8,7 +8,7 @@ - pylorax.ltmpl — Lorax 33.2 documentation + pylorax.ltmpl — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -183,25 +183,25 @@ logger = logging.getLogger("pylorax.ltmpl") import os, re, glob, shlex, fnmatch -from os.path import basename, isdir -from subprocess import CalledProcessError +from os.path import basename, isdir +from subprocess import CalledProcessError import shutil -from pylorax.sysutils import joinpaths, cpfile, mvfile, replace, remove -from pylorax.dnfhelper import LoraxDownloadCallback, LoraxRpmCallback -from pylorax.base import DataHolder -from pylorax.executils import runcmd, runcmd_output -from pylorax.imgutils import mkcpio +from pylorax.sysutils import joinpaths, cpfile, mvfile, replace, remove +from pylorax.dnfhelper import LoraxDownloadCallback, LoraxRpmCallback +from pylorax.base import DataHolder +from pylorax.executils import runcmd, runcmd_output +from pylorax.imgutils import mkcpio -from mako.lookup import TemplateLookup -from mako.exceptions import text_error_template +from mako.lookup import TemplateLookup +from mako.exceptions import text_error_template import sys, traceback import struct import dnf import collections.abc
[docs]class LoraxTemplate(object): - def __init__(self, directories=None): + def __init__(self, directories=None): directories = directories or ["/usr/share/lorax"] # we have to add ["/"] to the template lookup directories or the # file includes won't work properly for absolute paths @@ -290,7 +290,7 @@ * Parsing and execution are *separate* passes - so you can't use the result of a command in an %if statement (or any other control statements)! ''' - def __init__(self, fatalerrors=True, templatedir=None, defaults=None, builtins=None): + def __init__(self, fatalerrors=True, templatedir=None, defaults=None, builtins=None): self.fatalerrors = fatalerrors self.templatedir = templatedir or "/usr/share/lorax" self.templatefile = None @@ -376,7 +376,7 @@ * Commands should raise exceptions for errors - don't use sys.exit() ''' - def __init__(self, inroot, outroot, dbo=None, fatalerrors=True, + def __init__(self, inroot, outroot, dbo=None, fatalerrors=True, templatedir=None, defaults=None): self.inroot = inroot self.outroot = outroot @@ -419,9 +419,9 @@ pkgs = [] debug_pkgs = [] for p in list(self.dbo.transaction.install_set): - pkgs.append(f"{p.name}-{p.version}-{p.release}.{p.arch}") + pkgs.append(f"{p.name}-{p.version}-{p.release}.{p.arch}") if available.filter(name=p.name+"-debuginfo"): - debug_pkgs.append(f"{p.name}-debuginfo-{p.epoch}:{p.version}-{p.release}") + debug_pkgs.append(f"{p.name}-debuginfo-{p.epoch}:{p.version}-{p.release}") with open(self._out("root/lorax-packages.log"), "w") as f: f.write("\n".join(sorted(pkgs))) @@ -970,7 +970,7 @@ It is meant to be used with the live-install.tmpl which lists the per-arch pacages needed to build the live-iso output. """ - def __init__(self, dbo, fatalerrors=True, templatedir=None, defaults=None): + def __init__(self, dbo, fatalerrors=True, templatedir=None, defaults=None): self.dbo = dbo self.pkgs = [] self.pkgnames = [] diff --git a/docs/html/_modules/pylorax/monitor.html b/docs/html/_modules/pylorax/monitor.html index 602cb72e..30e40b86 100644 --- a/docs/html/_modules/pylorax/monitor.html +++ b/docs/html/_modules/pylorax/monitor.html @@ -8,7 +8,7 @@ - pylorax.monitor — Lorax 33.2 documentation + pylorax.monitor — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -297,7 +297,7 @@ # Number of seconds to wait for a connection after startup timeout = 60 - def __init__(self, log_path, *args, **kwargs): + def __init__(self, log_path, *args, **kwargs): """ Setup the log server @@ -335,7 +335,7 @@ This needs to be running before the virt-install runs, it expects there to be a listener on the port used for the virtio log port. """ - def __init__(self, log_path=None, host="localhost", port=0, timeout=None, log_request_handler_class=LogRequestHandler): + def __init__(self, log_path=None, host="localhost", port=0, timeout=None, log_request_handler_class=LogRequestHandler): """ Start a thread to monitor the logs. diff --git a/docs/html/_modules/pylorax/mount.html b/docs/html/_modules/pylorax/mount.html index 699858a0..c861493b 100644 --- a/docs/html/_modules/pylorax/mount.html +++ b/docs/html/_modules/pylorax/mount.html @@ -8,7 +8,7 @@ - pylorax.mount — Lorax 33.2 documentation + pylorax.mount — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -181,9 +181,9 @@ import os import pycdlib -from pycdlib.pycdlibexception import PyCdlibException +from pycdlib.pycdlibexception import PyCdlibException -from pylorax.imgutils import mount, umount +from pylorax.imgutils import mount, umount
[docs]class IsoMountpoint(object): """ @@ -194,7 +194,7 @@ stage2 can be either LiveOS/squashfs.img or images/install.img """ - def __init__(self, iso_path, initrd_path=None): + def __init__(self, iso_path, initrd_path=None): """ Mount the iso diff --git a/docs/html/_modules/pylorax/sysutils.html b/docs/html/_modules/pylorax/sysutils.html index 360ba745..db76cd9a 100644 --- a/docs/html/_modules/pylorax/sysutils.html +++ b/docs/html/_modules/pylorax/sysutils.html @@ -8,7 +8,7 @@ - pylorax.sysutils — Lorax 33.2 documentation + pylorax.sysutils — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -190,9 +190,9 @@ import glob import shutil import shlex -from configparser import ConfigParser +from configparser import ConfigParser -from pylorax.executils import runcmd +from pylorax.executils import runcmd
[docs]def joinpaths(*args, **kwargs): path = os.path.sep.join(args) diff --git a/docs/html/_modules/pylorax/treebuilder.html b/docs/html/_modules/pylorax/treebuilder.html index f0aacf3e..ae2615f2 100644 --- a/docs/html/_modules/pylorax/treebuilder.html +++ b/docs/html/_modules/pylorax/treebuilder.html @@ -8,7 +8,7 @@ - pylorax.treebuilder — Lorax 33.2 documentation + pylorax.treebuilder — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -180,17 +180,17 @@ logger = logging.getLogger("pylorax.treebuilder") import os, re -from os.path import basename -from shutil import copytree, copy2 -from subprocess import CalledProcessError -from pathlib import Path +from os.path import basename +from shutil import copytree, copy2 +from subprocess import CalledProcessError +from pathlib import Path import itertools -from pylorax.sysutils import joinpaths, remove -from pylorax.base import DataHolder -from pylorax.ltmpl import LoraxTemplateRunner +from pylorax.sysutils import joinpaths, remove +from pylorax.base import DataHolder +from pylorax.ltmpl import LoraxTemplateRunner import pylorax.imgutils as imgutils -from pylorax.executils import runcmd, runcmd_output, execWithCapture +from pylorax.executils import runcmd, runcmd_output, execWithCapture templatemap = { 'i386': 'x86.tmpl', @@ -227,7 +227,7 @@
[docs]class RuntimeBuilder(object): '''Builds the anaconda runtime image.''' - def __init__(self, product, arch, dbo, templatedir=None, + def __init__(self, product, arch, dbo, templatedir=None, installpkgs=None, excludepkgs=None, add_templates=None, add_template_vars=None, @@ -393,7 +393,7 @@ os.makedirs(os.path.dirname(outfile)) # squash the rootfs - imgutils.mksquashfs(self.vars.root, outfile, compression, compressargs)
+ return imgutils.mksquashfs(self.vars.root, outfile, compression, compressargs)
[docs] def create_ext4_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=None, size=2): """Create a squashfs compressed ext4 runtime""" @@ -412,8 +412,9 @@ raise # squash the live rootfs and clean up workdir - imgutils.mksquashfs(workdir, outfile, compression, compressargs) - remove(workdir)
+ rc = imgutils.mksquashfs(workdir, outfile, compression, compressargs) + remove(workdir) + return rc
[docs] def finished(self): """ Done using RuntimeBuilder @@ -425,7 +426,7 @@
[docs]class TreeBuilder(object): '''Builds the arch-specific boot images. inroot should be the installtree root (the newly-built runtime dir)''' - def __init__(self, product, arch, inroot, outroot, runtime, isolabel, domacboot=True, doupgrade=True, + def __init__(self, product, arch, inroot, outroot, runtime, isolabel, domacboot=True, doupgrade=True, templatedir=None, add_templates=None, add_template_vars=None, workdir=None, extra_boot_args=""): # NOTE: if you pass an arg named "runtime" to a mako template it'll @@ -466,8 +467,6 @@ if not self.kernels: raise Exception("No kernels found, cannot rebuild_initrds") - # Hush some dracut warnings. TODO: bind-mount proc in place? - open(joinpaths(self.vars.inroot,"/proc/modules"),"w") for kernel in self.kernels: if prefix: idir = os.path.dirname(kernel.path) @@ -479,14 +478,14 @@ # Construct an initrd from the kernel name outfile = kernel.path.replace("vmlinuz-", "initrd-") + ".img" logger.info("rebuilding %s", outfile) + logger.info("dracut warnings about /proc are safe to ignore") + if backup: initrd = joinpaths(self.vars.inroot, outfile) if os.path.exists(initrd): os.rename(initrd, initrd + backup) cmd = dracut + [outfile, kernel.version] - runcmd(cmd, root=self.vars.inroot) - - os.unlink(joinpaths(self.vars.inroot,"/proc/modules"))
+ runcmd(cmd, root=self.vars.inroot)
[docs] def build(self): templatefile = templatemap[self.vars.arch.basearch] diff --git a/docs/html/_modules/pylorax/treeinfo.html b/docs/html/_modules/pylorax/treeinfo.html index 41e417ad..0fb559b7 100644 --- a/docs/html/_modules/pylorax/treeinfo.html +++ b/docs/html/_modules/pylorax/treeinfo.html @@ -8,7 +8,7 @@ - pylorax.treeinfo — Lorax 33.2 documentation + pylorax.treeinfo — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -58,7 +58,7 @@
- 33.2 + 33.10
@@ -188,7 +188,7 @@
[docs]class TreeInfo(object): - def __init__(self, product, version, variant, basearch, + def __init__(self, product, version, variant, basearch, packagedir=""): self.c = configparser.ConfigParser() diff --git a/docs/html/_sources/composer-cli.rst.txt b/docs/html/_sources/composer-cli.rst.txt index c5857f32..83612e1d 100644 --- a/docs/html/_sources/composer-cli.rst.txt +++ b/docs/html/_sources/composer-cli.rst.txt @@ -4,12 +4,15 @@ composer-cli :Authors: Brian C. Lane -``composer-cli`` is used to interact with the ``lorax-composer`` API server, managing blueprints, exploring available packages, and building new images. +``composer-cli`` is an interactive tool for use with a WELDR API server, +managing blueprints, exploring available packages, and building new images. +`lorax-composer ` and `osbuild-composer +` both implement compatible servers. -It requires `lorax-composer `_ to be installed on the -local system, and the user running it needs to be a member of the ``weldr`` -group. They do not need to be root, but all of the `security precautions -`_ apply. +It requires the server to be installed on the local system, and the user +running it needs to be a member of the ``weldr`` group. They do not need to be +root, but all of the `security precautions `_ +apply. composer-cli cmdline arguments ------------------------------ @@ -76,6 +79,10 @@ with ``composer-cli upload start ...``. In order to access the service you need to pass authentication details to composer-cli using a TOML file, or reference a previously saved profile. +``lorax-composer`` and ``osbuild-composer`` handle this differently, with +``osbuild-composer`` you can currently only specify upload targets during the +compose process. + Providers --------- @@ -176,3 +183,21 @@ Or if you have the settings stored in a TOML file:: This will output the UUID of the upload, which can then be used to monitor the status in the same way described above. + + +Debugging +--------- + +There are a couple of arguments that can be helpful when debugging problems. +These are only meant for debugging and should not be used to script access to +the API. If you need to do that you can communicate with it directly in the +language of your choice. + +``--json`` will return the server's response as a nicely formatted json output +instead of printing what the command would usually print. + +``--test=1`` will cause a compose start to start creating an image, and then +end with a failed state. + +``--test=2`` will cause a compose to start and then end with a finished state, +without actually composing anything. diff --git a/docs/html/_sources/composer.cli.rst.txt b/docs/html/_sources/composer.cli.rst.txt index c1366a8e..4dd2e240 100644 --- a/docs/html/_sources/composer.cli.rst.txt +++ b/docs/html/_sources/composer.cli.rst.txt @@ -92,7 +92,6 @@ composer.cli.utilities module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/html/_sources/composer.rst.txt b/docs/html/_sources/composer.rst.txt index dd0c06cb..1ff06326 100644 --- a/docs/html/_sources/composer.rst.txt +++ b/docs/html/_sources/composer.rst.txt @@ -5,6 +5,7 @@ Subpackages ----------- .. toctree:: + :maxdepth: 4 composer.cli @@ -27,7 +28,6 @@ composer.unix\_socket module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/html/_sources/index.rst.txt b/docs/html/_sources/index.rst.txt index 9000845d..40a46d5e 100644 --- a/docs/html/_sources/index.rst.txt +++ b/docs/html/_sources/index.rst.txt @@ -23,6 +23,7 @@ Contents: Documentation for other Lorax Branches ====================================== +* `Fedora 32 `_ * `Fedora 31 `_ * `Fedora 30 `_ * `Fedora 29 `_ diff --git a/docs/html/_sources/lorax-composer.rst.txt b/docs/html/_sources/lorax-composer.rst.txt index e1dd9d18..d23be09c 100644 --- a/docs/html/_sources/lorax-composer.rst.txt +++ b/docs/html/_sources/lorax-composer.rst.txt @@ -4,7 +4,7 @@ lorax-composer :Authors: Brian C. Lane -``lorax-composer`` is an API server that allows you to build disk images using +``lorax-composer`` is a WELDR API server that allows you to build disk images using `Blueprints`_ to describe the package versions to be installed into the image. It is compatible with the Weldr project's bdcs-api REST protocol. More information on Weldr can be found `on the Weldr blog `_. @@ -13,6 +13,15 @@ Behind the scenes it uses `livemedia-creator `_ and `Anaconda `_ to handle the installation and configuration of the images. +.. note:: + + ``lorax-composer`` is now deprecated. It is being replaced by the + ``osbuild-composer`` WELDR API server which implements more features (eg. + ostree, image uploads, etc.) You can still use ``composer-cli`` and + ``cockpit-composer`` with ``osbuild-composer``. See the documentation or + the `osbuild website `_ for more information. + + Important Things To Note ------------------------ diff --git a/docs/html/_sources/pylorax.api.rst.txt b/docs/html/_sources/pylorax.api.rst.txt index 25a05cee..52b10944 100644 --- a/docs/html/_sources/pylorax.api.rst.txt +++ b/docs/html/_sources/pylorax.api.rst.txt @@ -164,7 +164,6 @@ pylorax.api.workspace module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/html/_sources/pylorax.rst.txt b/docs/html/_sources/pylorax.rst.txt index 2cd84475..13d2907b 100644 --- a/docs/html/_sources/pylorax.rst.txt +++ b/docs/html/_sources/pylorax.rst.txt @@ -5,6 +5,7 @@ Subpackages ----------- .. toctree:: + :maxdepth: 4 pylorax.api @@ -155,7 +156,6 @@ pylorax.treeinfo module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/html/_static/basic.css b/docs/html/_static/basic.css index c41d718e..24bc73e7 100644 --- a/docs/html/_static/basic.css +++ b/docs/html/_static/basic.css @@ -4,7 +4,7 @@ * * Sphinx stylesheet -- basic theme. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -15,6 +15,12 @@ div.clearer { clear: both; } +div.section::after { + display: block; + content: ''; + clear: left; +} + /* -- relbar ---------------------------------------------------------------- */ div.related { @@ -316,21 +322,27 @@ img.align-default, .figure.align-default { div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; - padding: 7px 7px 0 7px; + padding: 7px; background-color: #ffe; width: 40%; float: right; + clear: right; + overflow-x: auto; } p.sidebar-title { font-weight: bold; } +div.admonition, div.topic, blockquote { + clear: left; +} + /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; - padding: 7px 7px 0 7px; + padding: 7px; margin: 10px 0 10px 0; } @@ -352,10 +364,6 @@ div.admonition dt { font-weight: bold; } -div.admonition dl { - margin-bottom: 0; -} - p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; @@ -366,9 +374,28 @@ div.body p.centered { margin-top: 25px; } +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + /* -- tables ---------------------------------------------------------------- */ table.docutils { + margin-top: 10px; + margin-bottom: 10px; border: 0; border-collapse: collapse; } @@ -416,13 +443,13 @@ table.citation td { border-bottom: none; } -th > p:first-child, -td > p:first-child { +th > :first-child, +td > :first-child { margin-top: 0px; } -th > p:last-child, -td > p:last-child { +th > :last-child, +td > :last-child { margin-bottom: 0px; } @@ -468,6 +495,10 @@ table.field-list td, table.field-list th { /* -- hlist styles ---------------------------------------------------------- */ +table.hlist { + margin: 1em 0; +} + table.hlist td { vertical-align: top; } @@ -495,17 +526,37 @@ ol.upperroman { list-style: upper-roman; } -li > p:first-child { +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { margin-top: 0px; } -li > p:last-child { +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { margin-bottom: 0px; } +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + dl.footnote > dt, dl.citation > dt { float: left; + margin-right: 0.5em; } dl.footnote > dd, @@ -520,14 +571,15 @@ dl.citation > dd:after { } dl.field-list { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: fit-content(30%) auto; } dl.field-list > dt { - flex-basis: 20%; font-weight: bold; word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; } dl.field-list > dt:after { @@ -535,8 +587,8 @@ dl.field-list > dt:after { } dl.field-list > dd { - flex-basis: 70%; - padding-left: 1em; + padding-left: 0.5em; + margin-top: 0em; margin-left: 0em; margin-bottom: 0em; } @@ -545,7 +597,7 @@ dl { margin-bottom: 15px; } -dd > p:first-child { +dd > :first-child { margin-top: 0px; } @@ -559,6 +611,11 @@ dd { margin-left: 30px; } +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + dt:target, span.highlighted { background-color: #fbe54e; } @@ -636,6 +693,10 @@ pre { overflow-y: hidden; /* fixes display issues on Chrome browsers */ } +pre, div[class*="highlight-"] { + clear: both; +} + span.pre { -moz-hyphens: none; -ms-hyphens: none; @@ -643,22 +704,57 @@ span.pre { hyphens: none; } +div[class*="highlight-"] { + margin: 1em 0; +} + td.linenos pre { - padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { - margin-left: 0.5em; + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; } table.highlighttable td { - padding: 0 0.5em 0 0.5em; + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; } div.code-block-caption { + margin-top: 1em; padding: 2px 5px; font-size: small; } @@ -667,8 +763,9 @@ div.code-block-caption code { background-color: transparent; } -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; +table.highlighttable td.linenos, +div.doctest > div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; } div.code-block-caption span.caption-number { @@ -680,11 +777,7 @@ div.code-block-caption span.caption-text { } div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; + margin: 1em 0; } code.descname { @@ -735,8 +828,7 @@ span.eqno { } span.eqno a.headerlink { - position: relative; - left: 0px; + position: absolute; z-index: 1; } diff --git a/docs/html/_static/doctools.js b/docs/html/_static/doctools.js index b33f87fc..daccd209 100644 --- a/docs/html/_static/doctools.js +++ b/docs/html/_static/doctools.js @@ -4,7 +4,7 @@ * * Sphinx JavaScript utilities for all documentation. * - * :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + * :copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @@ -283,10 +283,11 @@ var Documentation = { }, initOnKeyListeners: function() { - $(document).keyup(function(event) { + $(document).keydown(function(event) { var activeElementType = document.activeElement.tagName; // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { + if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT' + && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) { switch (event.keyCode) { case 37: // left var prevHref = $('link[rel="prev"]').prop('href'); diff --git a/docs/html/_static/documentation_options.js b/docs/html/_static/documentation_options.js index c6a890c2..2db3f221 100644 --- a/docs/html/_static/documentation_options.js +++ b/docs/html/_static/documentation_options.js @@ -1,9 +1,11 @@ var DOCUMENTATION_OPTIONS = { URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), - VERSION: '33.2', + VERSION: '33.10', LANGUAGE: 'None', COLLAPSE_INDEX: false, + BUILDER: 'html', FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', HAS_SOURCE: true, SOURCELINK_SUFFIX: '.txt', NAVIGATION_WITH_KEYS: false diff --git a/docs/html/_static/jquery-3.5.1.js b/docs/html/_static/jquery-3.5.1.js new file mode 100644 index 00000000..50937333 --- /dev/null +++ b/docs/html/_static/jquery-3.5.1.js @@ -0,0 +1,10872 @@ +/*! + * jQuery JavaScript Library v3.5.1 + * https://jquery.com/ + * + * Includes Sizzle.js + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://jquery.org/license + * + * Date: 2020-05-04T22:49Z + */ +( function( global, factory ) { + + "use strict"; + + if ( typeof module === "object" && typeof module.exports === "object" ) { + + // For CommonJS and CommonJS-like environments where a proper `window` + // is present, execute the factory and get jQuery. + // For environments that do not have a `window` with a `document` + // (such as Node.js), expose a factory as module.exports. + // This accentuates the need for the creation of a real `window`. + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info. + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 +// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode +// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common +// enough that all such attempts are guarded in a try block. +"use strict"; + +var arr = []; + +var getProto = Object.getPrototypeOf; + +var slice = arr.slice; + +var flat = arr.flat ? function( array ) { + return arr.flat.call( array ); +} : function( array ) { + return arr.concat.apply( [], array ); +}; + + +var push = arr.push; + +var indexOf = arr.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var fnToString = hasOwn.toString; + +var ObjectFunctionString = fnToString.call( Object ); + +var support = {}; + +var isFunction = function isFunction( obj ) { + + // Support: Chrome <=57, Firefox <=52 + // In some browsers, typeof returns "function" for HTML elements + // (i.e., `typeof document.createElement( "object" ) === "function"`). + // We don't want to classify *any* DOM node as a function. + return typeof obj === "function" && typeof obj.nodeType !== "number"; + }; + + +var isWindow = function isWindow( obj ) { + return obj != null && obj === obj.window; + }; + + +var document = window.document; + + + + var preservedScriptAttributes = { + type: true, + src: true, + nonce: true, + noModule: true + }; + + function DOMEval( code, node, doc ) { + doc = doc || document; + + var i, val, + script = doc.createElement( "script" ); + + script.text = code; + if ( node ) { + for ( i in preservedScriptAttributes ) { + + // Support: Firefox 64+, Edge 18+ + // Some browsers don't support the "nonce" property on scripts. + // On the other hand, just using `getAttribute` is not enough as + // the `nonce` attribute is reset to an empty string whenever it + // becomes browsing-context connected. + // See https://github.com/whatwg/html/issues/2369 + // See https://html.spec.whatwg.org/#nonce-attributes + // The `node.getAttribute` check was added for the sake of + // `jQuery.globalEval` so that it can fake a nonce-containing node + // via an object. + val = node[ i ] || node.getAttribute && node.getAttribute( i ); + if ( val ) { + script.setAttribute( i, val ); + } + } + } + doc.head.appendChild( script ).parentNode.removeChild( script ); + } + + +function toType( obj ) { + if ( obj == null ) { + return obj + ""; + } + + // Support: Android <=2.3 only (functionish RegExp) + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call( obj ) ] || "object" : + typeof obj; +} +/* global Symbol */ +// Defining this global in .eslintrc.json would create a danger of using the global +// unguarded in another place, it seems safer to define global only for this module + + + +var + version = "3.5.1", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }; + +jQuery.fn = jQuery.prototype = { + + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + + // Return all the elements in a clean array + if ( num == null ) { + return slice.call( this ); + } + + // Return just the one element from the set + return num < 0 ? this[ num + this.length ] : this[ num ]; + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + each: function( callback ) { + return jQuery.each( this, callback ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map( this, function( elem, i ) { + return callback.call( elem, i, elem ); + } ) ); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + even: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return ( i + 1 ) % 2; + } ) ); + }, + + odd: function() { + return this.pushStack( jQuery.grep( this, function( _elem, i ) { + return i % 2; + } ) ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: arr.sort, + splice: arr.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[ 0 ] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // Skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !isFunction( target ) ) { + target = {}; + } + + // Extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + + // Only deal with non-null/undefined values + if ( ( options = arguments[ i ] ) != null ) { + + // Extend the base object + for ( name in options ) { + copy = options[ name ]; + + // Prevent Object.prototype pollution + // Prevent never-ending loop + if ( name === "__proto__" || target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject( copy ) || + ( copyIsArray = Array.isArray( copy ) ) ) ) { + src = target[ name ]; + + // Ensure proper type for the source value + if ( copyIsArray && !Array.isArray( src ) ) { + clone = []; + } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { + clone = {}; + } else { + clone = src; + } + copyIsArray = false; + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend( { + + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + isPlainObject: function( obj ) { + var proto, Ctor; + + // Detect obvious negatives + // Use toString instead of jQuery.type to catch host objects + if ( !obj || toString.call( obj ) !== "[object Object]" ) { + return false; + } + + proto = getProto( obj ); + + // Objects with no prototype (e.g., `Object.create( null )`) are plain + if ( !proto ) { + return true; + } + + // Objects with prototype are plain iff they were constructed by a global Object function + Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; + return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; + }, + + isEmptyObject: function( obj ) { + var name; + + for ( name in obj ) { + return false; + } + return true; + }, + + // Evaluates a script in a provided context; falls back to the global one + // if not specified. + globalEval: function( code, options, doc ) { + DOMEval( code, { nonce: options && options.nonce }, doc ); + }, + + each: function( obj, callback ) { + var length, i = 0; + + if ( isArrayLike( obj ) ) { + length = obj.length; + for ( ; i < length; i++ ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } else { + for ( i in obj ) { + if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { + break; + } + } + } + + return obj; + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArrayLike( Object( arr ) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + return arr == null ? -1 : indexOf.call( arr, elem, i ); + }, + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + for ( ; j < len; j++ ) { + first[ i++ ] = second[ j ]; + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var length, value, + i = 0, + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArrayLike( elems ) ) { + length = elems.length; + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return flat( ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +} ); + +if ( typeof Symbol === "function" ) { + jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; +} + +// Populate the class2type map +jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), +function( _i, name ) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +} ); + +function isArrayLike( obj ) { + + // Support: real iOS 8.2 only (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = !!obj && "length" in obj && obj.length, + type = toType( obj ); + + if ( isFunction( obj ) || isWindow( obj ) ) { + return false; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.3.5 + * https://sizzlejs.com/ + * + * Copyright JS Foundation and other contributors + * Released under the MIT license + * https://js.foundation/ + * + * Date: 2020-03-14 + */ +( function( window ) { +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + nonnativeSelectorCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // Instance methods + hasOwn = ( {} ).hasOwnProperty, + arr = [], + pop = arr.pop, + pushNative = arr.push, + push = arr.push, + slice = arr.slice, + + // Use a stripped-down indexOf as it's faster than native + // https://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[ i ] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + + "ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + + // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram + identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + + // "Attribute values must be CSS identifiers [capture 5] + // or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + + whitespace + "*\\]", + + pseudos = ":(" + identifier + ")(?:\\((" + + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + + "*" ), + rdescend = new RegExp( whitespace + "|>" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + identifier + ")" ), + "CLASS": new RegExp( "^\\.(" + identifier + ")" ), + "TAG": new RegExp( "^(" + identifier + "|[*])" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rhtml = /HTML$/i, + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + + // CSS escapes + // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), + funescape = function( escape, nonHex ) { + var high = "0x" + escape.slice( 1 ) - 0x10000; + + return nonHex ? + + // Strip the backslash prefix from a non-hex escape sequence + nonHex : + + // Replace a hexadecimal escape sequence with the encoded Unicode code point + // Support: IE <=11+ + // For values outside the Basic Multilingual Plane (BMP), manually construct a + // surrogate pair + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // CSS string/identifier serialization + // https://drafts.csswg.org/cssom/#common-serializing-idioms + rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + fcssescape = function( ch, asCodePoint ) { + if ( asCodePoint ) { + + // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER + if ( ch === "\0" ) { + return "\uFFFD"; + } + + // Control characters and (dependent upon position) numbers get escaped as code points + return ch.slice( 0, -1 ) + "\\" + + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; + } + + // Other potentially-special ASCII characters get backslash-escaped + return "\\" + ch; + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }, + + inDisabledFieldset = addCombinator( + function( elem ) { + return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; + }, + { dir: "parentNode", next: "legend" } + ); + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + ( arr = slice.call( preferredDoc.childNodes ) ), + preferredDoc.childNodes + ); + + // Support: Android<4.0 + // Detect silently failing push.apply + // eslint-disable-next-line no-unused-expressions + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + pushNative.apply( target, slice.call( els ) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + + // Can't trust NodeList.length + while ( ( target[ j++ ] = els[ i++ ] ) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var m, i, elem, nid, match, groups, newSelector, + newContext = context && context.ownerDocument, + + // nodeType defaults to 9, since context defaults to document + nodeType = context ? context.nodeType : 9; + + results = results || []; + + // Return early from calls with invalid selector or context + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + // Try to shortcut find operations (as opposed to filters) in HTML documents + if ( !seed ) { + setDocument( context ); + context = context || document; + + if ( documentIsHTML ) { + + // If the selector is sufficiently simple, try using a "get*By*" DOM method + // (excepting DocumentFragment context, where the methods don't exist) + if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { + + // ID selector + if ( ( m = match[ 1 ] ) ) { + + // Document context + if ( nodeType === 9 ) { + if ( ( elem = context.getElementById( m ) ) ) { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + + // Element context + } else { + + // Support: IE, Opera, Webkit + // TODO: identify versions + // getElementById can match elements by name instead of ID + if ( newContext && ( elem = newContext.getElementById( m ) ) && + contains( context, elem ) && + elem.id === m ) { + + results.push( elem ); + return results; + } + } + + // Type selector + } else if ( match[ 2 ] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Class selector + } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && + context.getElementsByClassName ) { + + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // Take advantage of querySelectorAll + if ( support.qsa && + !nonnativeSelectorCache[ selector + " " ] && + ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && + + // Support: IE 8 only + // Exclude object elements + ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { + + newSelector = selector; + newContext = context; + + // qSA considers elements outside a scoping root when evaluating child or + // descendant combinators, which is not what we want. + // In such cases, we work around the behavior by prefixing every selector in the + // list with an ID selector referencing the scope context. + // The technique has to be used as well when a leading combinator is used + // as such selectors are not recognized by querySelectorAll. + // Thanks to Andrew Dupont for this technique. + if ( nodeType === 1 && + ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { + + // Expand context for sibling selectors + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || + context; + + // We can use :scope instead of the ID hack if the browser + // supports it & if we're not changing the context. + if ( newContext !== context || !support.scope ) { + + // Capture the context ID, setting it first if necessary + if ( ( nid = context.getAttribute( "id" ) ) ) { + nid = nid.replace( rcssescape, fcssescape ); + } else { + context.setAttribute( "id", ( nid = expando ) ); + } + } + + // Prefix every selector in the list + groups = tokenize( selector ); + i = groups.length; + while ( i-- ) { + groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + + toSelector( groups[ i ] ); + } + newSelector = groups.join( "," ); + } + + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch ( qsaError ) { + nonnativeSelectorCache( selector, true ); + } finally { + if ( nid === expando ) { + context.removeAttribute( "id" ); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {function(string, object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return ( cache[ key + " " ] = value ); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created element and returns a boolean result + */ +function assert( fn ) { + var el = document.createElement( "fieldset" ); + + try { + return !!fn( el ); + } catch ( e ) { + return false; + } finally { + + // Remove from its parent by default + if ( el.parentNode ) { + el.parentNode.removeChild( el ); + } + + // release memory in IE + el = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split( "|" ), + i = arr.length; + + while ( i-- ) { + Expr.attrHandle[ arr[ i ] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + a.sourceIndex - b.sourceIndex; + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( ( cur = cur.nextSibling ) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return ( name === "input" || name === "button" ) && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for :enabled/:disabled + * @param {Boolean} disabled true for :disabled; false for :enabled + */ +function createDisabledPseudo( disabled ) { + + // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable + return function( elem ) { + + // Only certain elements can match :enabled or :disabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled + // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled + if ( "form" in elem ) { + + // Check for inherited disabledness on relevant non-disabled elements: + // * listed form-associated elements in a disabled fieldset + // https://html.spec.whatwg.org/multipage/forms.html#category-listed + // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled + // * option elements in a disabled optgroup + // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled + // All such elements have a "form" property. + if ( elem.parentNode && elem.disabled === false ) { + + // Option elements defer to a parent optgroup if present + if ( "label" in elem ) { + if ( "label" in elem.parentNode ) { + return elem.parentNode.disabled === disabled; + } else { + return elem.disabled === disabled; + } + } + + // Support: IE 6 - 11 + // Use the isDisabled shortcut property to check for disabled fieldset ancestors + return elem.isDisabled === disabled || + + // Where there is no isDisabled, check manually + /* jshint -W018 */ + elem.isDisabled !== !disabled && + inDisabledFieldset( elem ) === disabled; + } + + return elem.disabled === disabled; + + // Try to winnow out elements that can't be disabled before trusting the disabled property. + // Some victims get caught in our net (label, legend, menu, track), but it shouldn't + // even exist on them, let alone have a boolean value. + } else if ( "label" in elem ) { + return elem.disabled === disabled; + } + + // Remaining elements are neither :enabled nor :disabled + return false; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction( function( argument ) { + argument = +argument; + return markFunction( function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ ( j = matchIndexes[ i ] ) ] ) { + seed[ j ] = !( matches[ j ] = seed[ j ] ); + } + } + } ); + } ); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + var namespace = elem.namespaceURI, + docElem = ( elem.ownerDocument || elem ).documentElement; + + // Support: IE <=8 + // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes + // https://bugs.jquery.com/ticket/4833 + return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, subWindow, + doc = node ? node.ownerDocument || node : preferredDoc; + + // Return early if doc is invalid or already selected + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Update global variables + document = doc; + docElem = document.documentElement; + documentIsHTML = !isXML( document ); + + // Support: IE 9 - 11+, Edge 12 - 18+ + // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( preferredDoc != document && + ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { + + // Support: IE 11, Edge + if ( subWindow.addEventListener ) { + subWindow.addEventListener( "unload", unloadHandler, false ); + + // Support: IE 9 - 10 only + } else if ( subWindow.attachEvent ) { + subWindow.attachEvent( "onunload", unloadHandler ); + } + } + + // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, + // Safari 4 - 5 only, Opera <=11.6 - 12.x only + // IE/Edge & older browsers don't support the :scope pseudo-class. + // Support: Safari 6.0 only + // Safari 6.0 supports :scope but it's an alias of :root there. + support.scope = assert( function( el ) { + docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); + return typeof el.querySelectorAll !== "undefined" && + !el.querySelectorAll( ":scope fieldset div" ).length; + } ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert( function( el ) { + el.className = "i"; + return !el.getAttribute( "className" ); + } ); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert( function( el ) { + el.appendChild( document.createComment( "" ) ); + return !el.getElementsByTagName( "*" ).length; + } ); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( document.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programmatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert( function( el ) { + docElem.appendChild( el ).id = expando; + return !document.getElementsByName || !document.getElementsByName( expando ).length; + } ); + + // ID filter and find + if ( support.getById ) { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute( "id" ) === attrId; + }; + }; + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var elem = context.getElementById( id ); + return elem ? [ elem ] : []; + } + }; + } else { + Expr.filter[ "ID" ] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && + elem.getAttributeNode( "id" ); + return node && node.value === attrId; + }; + }; + + // Support: IE 6 - 7 only + // getElementById is not reliable as a find shortcut + Expr.find[ "ID" ] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var node, i, elems, + elem = context.getElementById( id ); + + if ( elem ) { + + // Verify the id attribute + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + + // Fall back on getElementsByName + elems = context.getElementsByName( id ); + i = 0; + while ( ( elem = elems[ i++ ] ) ) { + node = elem.getAttributeNode( "id" ); + if ( node && node.value === id ) { + return [ elem ]; + } + } + } + + return []; + } + }; + } + + // Tag + Expr.find[ "TAG" ] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See https://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert( function( el ) { + + var input; + + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // https://bugs.jquery.com/ticket/12359 + docElem.appendChild( el ).innerHTML = "" + + ""; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !el.querySelectorAll( "[selected]" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ + if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push( "~=" ); + } + + // Support: IE 11+, Edge 15 - 18+ + // IE 11/Edge don't find elements on a `[name='']` query in some cases. + // Adding a temporary attribute to the document before the selection works + // around the issue. + // Interestingly, IE 10 & older don't seem to have the issue. + input = document.createElement( "input" ); + input.setAttribute( "name", "" ); + el.appendChild( input ); + if ( !el.querySelectorAll( "[name='']" ).length ) { + rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + + whitespace + "*(?:''|\"\")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !el.querySelectorAll( ":checked" ).length ) { + rbuggyQSA.push( ":checked" ); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibling-combinator selector` fails + if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push( ".#.+[+~]" ); + } + + // Support: Firefox <=3.6 - 5 only + // Old Firefox doesn't throw on a badly-escaped identifier. + el.querySelectorAll( "\\\f" ); + rbuggyQSA.push( "[\\r\\n\\f]" ); + } ); + + assert( function( el ) { + el.innerHTML = "" + + ""; + + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = document.createElement( "input" ); + input.setAttribute( "type", "hidden" ); + el.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( el.querySelectorAll( "[name=d]" ).length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: IE9-11+ + // IE's :disabled selector does not pick up the children of disabled fieldsets + docElem.appendChild( el ).disabled = true; + if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Support: Opera 10 - 11 only + // Opera 10-11 does not throw on post-comma invalid pseudos + el.querySelectorAll( "*,:x" ); + rbuggyQSA.push( ",.*:" ); + } ); + } + + if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector ) ) ) ) { + + assert( function( el ) { + + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( el, "*" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( el, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + } ); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully self-exclusive + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + ) ); + } : + function( a, b ) { + if ( b ) { + while ( ( b = b.parentNode ) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { + + // Choose the first element that is related to our preferred document + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( a == document || a.ownerDocument == preferredDoc && + contains( preferredDoc, a ) ) { + return -1; + } + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( b == document || b.ownerDocument == preferredDoc && + contains( preferredDoc, b ) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + return a == document ? -1 : + b == document ? 1 : + /* eslint-enable eqeqeq */ + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( ( cur = cur.parentNode ) ) { + ap.unshift( cur ); + } + cur = b; + while ( ( cur = cur.parentNode ) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[ i ] === bp[ i ] ) { + i++; + } + + return i ? + + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[ i ], bp[ i ] ) : + + // Otherwise nodes in our document sort first + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + /* eslint-disable eqeqeq */ + ap[ i ] == preferredDoc ? -1 : + bp[ i ] == preferredDoc ? 1 : + /* eslint-enable eqeqeq */ + 0; + }; + + return document; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + setDocument( elem ); + + if ( support.matchesSelector && documentIsHTML && + !nonnativeSelectorCache[ expr + " " ] && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch ( e ) { + nonnativeSelectorCache( expr, true ); + } + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( context.ownerDocument || context ) != document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + + // Set document vars if needed + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( ( elem.ownerDocument || elem ) != document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; +}; + +Sizzle.escape = function( sel ) { + return ( sel + "" ).replace( rcssescape, fcssescape ); +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( ( elem = results[ i++ ] ) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + + // If no nodeType, this is expected to be an array + while ( ( node = elem[ i++ ] ) ) { + + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[ 1 ] = match[ 1 ].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[ 3 ] = ( match[ 3 ] || match[ 4 ] || + match[ 5 ] || "" ).replace( runescape, funescape ); + + if ( match[ 2 ] === "~=" ) { + match[ 3 ] = " " + match[ 3 ] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[ 1 ] = match[ 1 ].toLowerCase(); + + if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { + + // nth-* requires argument + if ( !match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[ 4 ] = +( match[ 4 ] ? + match[ 5 ] + ( match[ 6 ] || 1 ) : + 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); + match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); + + // other types prohibit arguments + } else if ( match[ 3 ] ) { + Sizzle.error( match[ 0 ] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[ 6 ] && match[ 2 ]; + + if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[ 3 ] ) { + match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + + // Get excess from tokenize (recursively) + ( excess = tokenize( unquoted, true ) ) && + + // advance to the next closing parenthesis + ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { + + // excess is a negative index + match[ 0 ] = match[ 0 ].slice( 0, excess ); + match[ 2 ] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { + return true; + } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + ( pattern = new RegExp( "(^|" + whitespace + + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( + className, function( elem ) { + return pattern.test( + typeof elem.className === "string" && elem.className || + typeof elem.getAttribute !== "undefined" && + elem.getAttribute( "class" ) || + "" + ); + } ); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + /* eslint-disable max-len */ + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + /* eslint-enable max-len */ + + }; + }, + + "CHILD": function( type, what, _argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, _context, xml ) { + var cache, uniqueCache, outerCache, node, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType, + diff = false; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( ( node = node[ dir ] ) ) { + if ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) { + + return false; + } + } + + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + + // Seek `elem` from a previously-cached index + + // ...in a gzip-friendly way + node = parent; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex && cache[ 2 ]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( ( node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + } else { + + // Use previously-cached element index if available + if ( useCache ) { + + // ...in a gzip-friendly way + node = elem; + outerCache = node[ expando ] || ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + cache = uniqueCache[ type ] || []; + nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; + diff = nodeIndex; + } + + // xml :nth-child(...) + // or :nth-last-child(...) or :nth(-last)?-of-type(...) + if ( diff === false ) { + + // Use the same loop as above to seek `elem` from the start + while ( ( node = ++nodeIndex && node && node[ dir ] || + ( diff = nodeIndex = 0 ) || start.pop() ) ) { + + if ( ( ofType ? + node.nodeName.toLowerCase() === name : + node.nodeType === 1 ) && + ++diff ) { + + // Cache the index of each encountered element + if ( useCache ) { + outerCache = node[ expando ] || + ( node[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ node.uniqueID ] || + ( outerCache[ node.uniqueID ] = {} ); + + uniqueCache[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction( function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[ i ] ); + seed[ idx ] = !( matches[ idx ] = matched[ i ] ); + } + } ) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + + // Potentially complex pseudos + "not": markFunction( function( selector ) { + + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction( function( seed, matches, _context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( ( elem = unmatched[ i ] ) ) { + seed[ i ] = !( matches[ i ] = elem ); + } + } + } ) : + function( elem, _context, xml ) { + input[ 0 ] = elem; + matcher( input, null, xml, results ); + + // Don't keep the element (issue #299) + input[ 0 ] = null; + return !results.pop(); + }; + } ), + + "has": markFunction( function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + } ), + + "contains": markFunction( function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; + }; + } ), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + + // lang value must be a valid identifier + if ( !ridentifier.test( lang || "" ) ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( ( elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); + return false; + }; + } ), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && + ( !document.hasFocus || document.hasFocus() ) && + !!( elem.type || elem.href || ~elem.tabIndex ); + }, + + // Boolean properties + "enabled": createDisabledPseudo( false ), + "disabled": createDisabledPseudo( true ), + + "checked": function( elem ) { + + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return ( nodeName === "input" && !!elem.checked ) || + ( nodeName === "option" && !!elem.selected ); + }, + + "selected": function( elem ) { + + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + // eslint-disable-next-line no-unused-expressions + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos[ "empty" ]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( ( attr = elem.getAttribute( "type" ) ) == null || + attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo( function() { + return [ 0 ]; + } ), + + "last": createPositionalPseudo( function( _matchIndexes, length ) { + return [ length - 1 ]; + } ), + + "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + } ), + + "even": createPositionalPseudo( function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "odd": createPositionalPseudo( function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? + argument + length : + argument > length ? + length : + argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ), + + "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + } ) + } +}; + +Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || ( match = rcomma.exec( soFar ) ) ) { + if ( match ) { + + // Don't consume trailing commas as valid + soFar = soFar.slice( match[ 0 ].length ) || soFar; + } + groups.push( ( tokens = [] ) ); + } + + matched = false; + + // Combinators + if ( ( match = rcombinators.exec( soFar ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + + // Cast descendant combinators to space + type: match[ 0 ].replace( rtrim, " " ) + } ); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || + ( match = preFilters[ type ]( match ) ) ) ) { + matched = match.shift(); + tokens.push( { + value: matched, + type: type, + matches: match + } ); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[ i ].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + skip = combinator.next, + key = skip || dir, + checkNonElements = base && key === "parentNode", + doneName = done++; + + return combinator.first ? + + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + return false; + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, uniqueCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching + if ( xml ) { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( ( elem = elem[ dir ] ) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || ( elem[ expando ] = {} ); + + // Support: IE <9 only + // Defend against cloned attroperties (jQuery gh-1709) + uniqueCache = outerCache[ elem.uniqueID ] || + ( outerCache[ elem.uniqueID ] = {} ); + + if ( skip && skip === elem.nodeName.toLowerCase() ) { + elem = elem[ dir ] || elem; + } else if ( ( oldCache = uniqueCache[ key ] ) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return ( newCache[ 2 ] = oldCache[ 2 ] ); + } else { + + // Reuse newcache so results back-propagate to previous elements + uniqueCache[ key ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { + return true; + } + } + } + } + } + return false; + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[ i ]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[ 0 ]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[ i ], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( ( elem = unmatched[ i ] ) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction( function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( + selector || "*", + context.nodeType ? [ context ] : context, + [] + ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( ( elem = temp[ i ] ) ) { + matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) ) { + + // Restore matcherIn since elem is not yet a final match + temp.push( ( matcherIn[ i ] = elem ) ); + } + } + postFinder( null, ( matcherOut = [] ), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( ( elem = matcherOut[ i ] ) && + ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { + + seed[ temp ] = !( results[ temp ] = elem ); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + } ); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[ 0 ].type ], + implicitRelative = leadingRelative || Expr.relative[ " " ], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + ( checkContext = context ).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[ j ].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens + .slice( 0, i - 1 ) + .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), + + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), + len = elems.length; + + if ( outermost ) { + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + outermostContext = context == document || context || outermost; + } + + // Add elements passing elementMatchers directly to results + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id + for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + + // Support: IE 11+, Edge 17 - 18+ + // IE/Edge sometimes throw a "Permission denied" error when strict-comparing + // two documents; shallow comparisons work. + // eslint-disable-next-line eqeqeq + if ( !context && elem.ownerDocument != document ) { + setDocument( elem ); + xml = !documentIsHTML; + } + while ( ( matcher = elementMatchers[ j++ ] ) ) { + if ( matcher( elem, context || document, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + + // They will have gone through all possible matchers + if ( ( elem = !matcher && elem ) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // `i` is now the count of elements visited above, and adding it to `matchedCount` + // makes the latter nonnegative. + matchedCount += i; + + // Apply set filters to unmatched elements + // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` + // equals `i`), unless we didn't visit _any_ elements in the above loop because we have + // no element matchers and no seed. + // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that + // case, which will result in a "00" `matchedCount` that differs from `i` but is also + // numerically zero. + if ( bySet && i !== matchedCount ) { + j = 0; + while ( ( matcher = setMatchers[ j++ ] ) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !( unmatched[ i ] || setMatched[ i ] ) ) { + setMatched[ i ] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[ i ] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( + selector, + matcherFromGroupMatchers( elementMatchers, setMatchers ) + ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( ( selector = compiled.selector || selector ) ); + + results = results || []; + + // Try to minimize operations if there is only one selector in the list and no seed + // (the latter of which guarantees us context) + if ( match.length === 1 ) { + + // Reduce context if the leading compound selector is an ID + tokens = match[ 0 ] = match[ 0 ].slice( 0 ); + if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && + context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { + + context = ( Expr.find[ "ID" ]( token.matches[ 0 ] + .replace( runescape, funescape ), context ) || [] )[ 0 ]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[ i ]; + + // Abort if we hit a combinator + if ( Expr.relative[ ( type = token.type ) ] ) { + break; + } + if ( ( find = Expr.find[ type ] ) ) { + + // Search, expanding context for leading sibling combinators + if ( ( seed = find( + token.matches[ 0 ].replace( runescape, funescape ), + rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || + context + ) ) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + !context || rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert( function( el ) { + + // Should return 1, but returns 4 (following) + return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; +} ); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert( function( el ) { + el.innerHTML = ""; + return el.firstChild.getAttribute( "href" ) === "#"; +} ) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + } ); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert( function( el ) { + el.innerHTML = ""; + el.firstChild.setAttribute( "value", "" ); + return el.firstChild.getAttribute( "value" ) === ""; +} ) ) { + addHandle( "value", function( elem, _name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + } ); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert( function( el ) { + return el.getAttribute( "disabled" ) == null; +} ) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + ( val = elem.getAttributeNode( name ) ) && val.specified ? + val.value : + null; + } + } ); +} + +return Sizzle; + +} )( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; + +// Deprecated +jQuery.expr[ ":" ] = jQuery.expr.pseudos; +jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; +jQuery.escapeSelector = Sizzle.escape; + + + + +var dir = function( elem, dir, until ) { + var matched = [], + truncate = until !== undefined; + + while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { + if ( elem.nodeType === 1 ) { + if ( truncate && jQuery( elem ).is( until ) ) { + break; + } + matched.push( elem ); + } + } + return matched; +}; + + +var siblings = function( n, elem ) { + var matched = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + matched.push( n ); + } + } + + return matched; +}; + + +var rneedsContext = jQuery.expr.match.needsContext; + + + +function nodeName( elem, name ) { + + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + +}; +var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); + + + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + return !!qualifier.call( elem, i, elem ) !== not; + } ); + } + + // Single element + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + } ); + } + + // Arraylike of elements (jQuery, arguments, Array) + if ( typeof qualifier !== "string" ) { + return jQuery.grep( elements, function( elem ) { + return ( indexOf.call( qualifier, elem ) > -1 ) !== not; + } ); + } + + // Filtered directly for both simple and complex selectors + return jQuery.filter( qualifier, elements, not ); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + if ( elems.length === 1 && elem.nodeType === 1 ) { + return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; + } + + return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + } ) ); +}; + +jQuery.fn.extend( { + find: function( selector ) { + var i, ret, + len = this.length, + self = this; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter( function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + } ) ); + } + + ret = this.pushStack( [] ); + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + return len > 1 ? jQuery.uniqueSort( ret ) : ret; + }, + filter: function( selector ) { + return this.pushStack( winnow( this, selector || [], false ) ); + }, + not: function( selector ) { + return this.pushStack( winnow( this, selector || [], true ) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +} ); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + // Shortcut simple #id case for speed + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, + + init = jQuery.fn.init = function( selector, context, root ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Method init() accepts an alternate rootjQuery + // so migrate can support jQuery.sub (gh-2101) + root = root || rootjQuery; + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector[ 0 ] === "<" && + selector[ selector.length - 1 ] === ">" && + selector.length >= 3 ) { + + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && ( match[ 1 ] || !context ) ) { + + // HANDLE: $(html) -> $(array) + if ( match[ 1 ] ) { + context = context instanceof jQuery ? context[ 0 ] : context; + + // Option to run scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[ 1 ], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + + // Properties of context are called as methods if possible + if ( isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[ 2 ] ); + + if ( elem ) { + + // Inject the element directly into the jQuery object + this[ 0 ] = elem; + this.length = 1; + } + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || root ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this[ 0 ] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( isFunction( selector ) ) { + return root.ready !== undefined ? + root.ready( selector ) : + + // Execute immediately if ready is not present + selector( jQuery ); + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + + // Methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend( { + has: function( target ) { + var targets = jQuery( target, this ), + l = targets.length; + + return this.filter( function() { + var i = 0; + for ( ; i < l; i++ ) { + if ( jQuery.contains( this, targets[ i ] ) ) { + return true; + } + } + } ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + targets = typeof selectors !== "string" && jQuery( selectors ); + + // Positional selectors never match, since there's no _selection_ context + if ( !rneedsContext.test( selectors ) ) { + for ( ; i < l; i++ ) { + for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { + + // Always skip document fragments + if ( cur.nodeType < 11 && ( targets ? + targets.index( cur ) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector( cur, selectors ) ) ) { + + matched.push( cur ); + break; + } + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); + }, + + // Determine the position of an element within the set + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; + } + + // Index in selector + if ( typeof elem === "string" ) { + return indexOf.call( jQuery( elem ), this[ 0 ] ); + } + + // Locate the position of the desired element + return indexOf.call( this, + + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[ 0 ] : elem + ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.uniqueSort( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter( selector ) + ); + } +} ); + +function sibling( cur, dir ) { + while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} + return cur; +} + +jQuery.each( { + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, _i, until ) { + return dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, _i, until ) { + return dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, _i, until ) { + return dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return siblings( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return siblings( elem.firstChild ); + }, + contents: function( elem ) { + if ( elem.contentDocument != null && + + // Support: IE 11+ + // elements with no `data` attribute has an object + // `contentDocument` with a `null` prototype. + getProto( elem.contentDocument ) ) { + + return elem.contentDocument; + } + + // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only + // Treat the template element as a regular one in browsers that + // don't support it. + if ( nodeName( elem, "template" ) ) { + elem = elem.content || elem; + } + + return jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var matched = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + matched = jQuery.filter( selector, matched ); + } + + if ( this.length > 1 ) { + + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + jQuery.uniqueSort( matched ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + matched.reverse(); + } + } + + return this.pushStack( matched ); + }; +} ); +var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); + + + +// Convert String-formatted options into Object-formatted ones +function createOptions( options ) { + var object = {}; + jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { + object[ flag ] = true; + } ); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + createOptions( options ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + + // Last fire value for non-forgettable lists + memory, + + // Flag to know if list was already fired + fired, + + // Flag to prevent firing + locked, + + // Actual callback list + list = [], + + // Queue of execution data for repeatable lists + queue = [], + + // Index of currently firing callback (modified by add/remove as needed) + firingIndex = -1, + + // Fire callbacks + fire = function() { + + // Enforce single-firing + locked = locked || options.once; + + // Execute callbacks for all pending executions, + // respecting firingIndex overrides and runtime changes + fired = firing = true; + for ( ; queue.length; firingIndex = -1 ) { + memory = queue.shift(); + while ( ++firingIndex < list.length ) { + + // Run callback and check for early termination + if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && + options.stopOnFalse ) { + + // Jump to end and forget the data so .add doesn't re-fire + firingIndex = list.length; + memory = false; + } + } + } + + // Forget the data if we're done with it + if ( !options.memory ) { + memory = false; + } + + firing = false; + + // Clean up if we're done firing for good + if ( locked ) { + + // Keep an empty list if we have data for future add calls + if ( memory ) { + list = []; + + // Otherwise, this object is spent + } else { + list = ""; + } + } + }, + + // Actual Callbacks object + self = { + + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + + // If we have memory from a past run, we should fire after adding + if ( memory && !firing ) { + firingIndex = list.length - 1; + queue.push( memory ); + } + + ( function add( args ) { + jQuery.each( args, function( _, arg ) { + if ( isFunction( arg ) ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && toType( arg ) !== "string" ) { + + // Inspect recursively + add( arg ); + } + } ); + } )( arguments ); + + if ( memory && !firing ) { + fire(); + } + } + return this; + }, + + // Remove a callback from the list + remove: function() { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + + // Handle firing indexes + if ( index <= firingIndex ) { + firingIndex--; + } + } + } ); + return this; + }, + + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? + jQuery.inArray( fn, list ) > -1 : + list.length > 0; + }, + + // Remove all callbacks from the list + empty: function() { + if ( list ) { + list = []; + } + return this; + }, + + // Disable .fire and .add + // Abort any current/pending executions + // Clear all callbacks and values + disable: function() { + locked = queue = []; + list = memory = ""; + return this; + }, + disabled: function() { + return !list; + }, + + // Disable .fire + // Also disable .add unless we have memory (since it would have no effect) + // Abort any pending executions + lock: function() { + locked = queue = []; + if ( !memory && !firing ) { + list = memory = ""; + } + return this; + }, + locked: function() { + return !!locked; + }, + + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( !locked ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + queue.push( args ); + if ( !firing ) { + fire(); + } + } + return this; + }, + + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +function Identity( v ) { + return v; +} +function Thrower( ex ) { + throw ex; +} + +function adoptValue( value, resolve, reject, noValue ) { + var method; + + try { + + // Check for promise aspect first to privilege synchronous behavior + if ( value && isFunction( ( method = value.promise ) ) ) { + method.call( value ).done( resolve ).fail( reject ); + + // Other thenables + } else if ( value && isFunction( ( method = value.then ) ) ) { + method.call( value, resolve, reject ); + + // Other non-thenables + } else { + + // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: + // * false: [ value ].slice( 0 ) => resolve( value ) + // * true: [ value ].slice( 1 ) => resolve() + resolve.apply( undefined, [ value ].slice( noValue ) ); + } + + // For Promises/A+, convert exceptions into rejections + // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in + // Deferred#then to conditionally suppress rejection. + } catch ( value ) { + + // Support: Android 4.0 only + // Strict mode functions invoked without .call/.apply get global-object context + reject.apply( undefined, [ value ] ); + } +} + +jQuery.extend( { + + Deferred: function( func ) { + var tuples = [ + + // action, add listener, callbacks, + // ... .then handlers, argument index, [final state] + [ "notify", "progress", jQuery.Callbacks( "memory" ), + jQuery.Callbacks( "memory" ), 2 ], + [ "resolve", "done", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 0, "resolved" ], + [ "reject", "fail", jQuery.Callbacks( "once memory" ), + jQuery.Callbacks( "once memory" ), 1, "rejected" ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + "catch": function( fn ) { + return promise.then( null, fn ); + }, + + // Keep pipe for back-compat + pipe: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + + return jQuery.Deferred( function( newDefer ) { + jQuery.each( tuples, function( _i, tuple ) { + + // Map tuples (progress, done, fail) to arguments (done, fail, progress) + var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; + + // deferred.progress(function() { bind to newDefer or newDefer.notify }) + // deferred.done(function() { bind to newDefer or newDefer.resolve }) + // deferred.fail(function() { bind to newDefer or newDefer.reject }) + deferred[ tuple[ 1 ] ]( function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && isFunction( returned.promise ) ) { + returned.promise() + .progress( newDefer.notify ) + .done( newDefer.resolve ) + .fail( newDefer.reject ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( + this, + fn ? [ returned ] : arguments + ); + } + } ); + } ); + fns = null; + } ).promise(); + }, + then: function( onFulfilled, onRejected, onProgress ) { + var maxDepth = 0; + function resolve( depth, deferred, handler, special ) { + return function() { + var that = this, + args = arguments, + mightThrow = function() { + var returned, then; + + // Support: Promises/A+ section 2.3.3.3.3 + // https://promisesaplus.com/#point-59 + // Ignore double-resolution attempts + if ( depth < maxDepth ) { + return; + } + + returned = handler.apply( that, args ); + + // Support: Promises/A+ section 2.3.1 + // https://promisesaplus.com/#point-48 + if ( returned === deferred.promise() ) { + throw new TypeError( "Thenable self-resolution" ); + } + + // Support: Promises/A+ sections 2.3.3.1, 3.5 + // https://promisesaplus.com/#point-54 + // https://promisesaplus.com/#point-75 + // Retrieve `then` only once + then = returned && + + // Support: Promises/A+ section 2.3.4 + // https://promisesaplus.com/#point-64 + // Only check objects and functions for thenability + ( typeof returned === "object" || + typeof returned === "function" ) && + returned.then; + + // Handle a returned thenable + if ( isFunction( then ) ) { + + // Special processors (notify) just wait for resolution + if ( special ) { + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ) + ); + + // Normal processors (resolve) also hook into progress + } else { + + // ...and disregard older resolution values + maxDepth++; + + then.call( + returned, + resolve( maxDepth, deferred, Identity, special ), + resolve( maxDepth, deferred, Thrower, special ), + resolve( maxDepth, deferred, Identity, + deferred.notifyWith ) + ); + } + + // Handle all other returned values + } else { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Identity ) { + that = undefined; + args = [ returned ]; + } + + // Process the value(s) + // Default process is resolve + ( special || deferred.resolveWith )( that, args ); + } + }, + + // Only normal processors (resolve) catch and reject exceptions + process = special ? + mightThrow : + function() { + try { + mightThrow(); + } catch ( e ) { + + if ( jQuery.Deferred.exceptionHook ) { + jQuery.Deferred.exceptionHook( e, + process.stackTrace ); + } + + // Support: Promises/A+ section 2.3.3.3.4.1 + // https://promisesaplus.com/#point-61 + // Ignore post-resolution exceptions + if ( depth + 1 >= maxDepth ) { + + // Only substitute handlers pass on context + // and multiple values (non-spec behavior) + if ( handler !== Thrower ) { + that = undefined; + args = [ e ]; + } + + deferred.rejectWith( that, args ); + } + } + }; + + // Support: Promises/A+ section 2.3.3.3.1 + // https://promisesaplus.com/#point-57 + // Re-resolve promises immediately to dodge false rejection from + // subsequent errors + if ( depth ) { + process(); + } else { + + // Call an optional hook to record the stack, in case of exception + // since it's otherwise lost when execution goes async + if ( jQuery.Deferred.getStackHook ) { + process.stackTrace = jQuery.Deferred.getStackHook(); + } + window.setTimeout( process ); + } + }; + } + + return jQuery.Deferred( function( newDefer ) { + + // progress_handlers.add( ... ) + tuples[ 0 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onProgress ) ? + onProgress : + Identity, + newDefer.notifyWith + ) + ); + + // fulfilled_handlers.add( ... ) + tuples[ 1 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onFulfilled ) ? + onFulfilled : + Identity + ) + ); + + // rejected_handlers.add( ... ) + tuples[ 2 ][ 3 ].add( + resolve( + 0, + newDefer, + isFunction( onRejected ) ? + onRejected : + Thrower + ) + ); + } ).promise(); + }, + + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 5 ]; + + // promise.progress = list.add + // promise.done = list.add + // promise.fail = list.add + promise[ tuple[ 1 ] ] = list.add; + + // Handle state + if ( stateString ) { + list.add( + function() { + + // state = "resolved" (i.e., fulfilled) + // state = "rejected" + state = stateString; + }, + + // rejected_callbacks.disable + // fulfilled_callbacks.disable + tuples[ 3 - i ][ 2 ].disable, + + // rejected_handlers.disable + // fulfilled_handlers.disable + tuples[ 3 - i ][ 3 ].disable, + + // progress_callbacks.lock + tuples[ 0 ][ 2 ].lock, + + // progress_handlers.lock + tuples[ 0 ][ 3 ].lock + ); + } + + // progress_handlers.fire + // fulfilled_handlers.fire + // rejected_handlers.fire + list.add( tuple[ 3 ].fire ); + + // deferred.notify = function() { deferred.notifyWith(...) } + // deferred.resolve = function() { deferred.resolveWith(...) } + // deferred.reject = function() { deferred.rejectWith(...) } + deferred[ tuple[ 0 ] ] = function() { + deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); + return this; + }; + + // deferred.notifyWith = list.fireWith + // deferred.resolveWith = list.fireWith + // deferred.rejectWith = list.fireWith + deferred[ tuple[ 0 ] + "With" ] = list.fireWith; + } ); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( singleValue ) { + var + + // count of uncompleted subordinates + remaining = arguments.length, + + // count of unprocessed arguments + i = remaining, + + // subordinate fulfillment data + resolveContexts = Array( i ), + resolveValues = slice.call( arguments ), + + // the master Deferred + master = jQuery.Deferred(), + + // subordinate callback factory + updateFunc = function( i ) { + return function( value ) { + resolveContexts[ i ] = this; + resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( !( --remaining ) ) { + master.resolveWith( resolveContexts, resolveValues ); + } + }; + }; + + // Single- and empty arguments are adopted like Promise.resolve + if ( remaining <= 1 ) { + adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, + !remaining ); + + // Use .then() to unwrap secondary thenables (cf. gh-3000) + if ( master.state() === "pending" || + isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { + + return master.then(); + } + } + + // Multiple arguments are aggregated like Promise.all array elements + while ( i-- ) { + adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); + } + + return master.promise(); + } +} ); + + +// These usually indicate a programmer mistake during development, +// warn about them ASAP rather than swallowing them by default. +var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + +jQuery.Deferred.exceptionHook = function( error, stack ) { + + // Support: IE 8 - 9 only + // Console exists when dev tools are open, which can happen at any time + if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { + window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); + } +}; + + + + +jQuery.readyException = function( error ) { + window.setTimeout( function() { + throw error; + } ); +}; + + + + +// The deferred used on DOM ready +var readyList = jQuery.Deferred(); + +jQuery.fn.ready = function( fn ) { + + readyList + .then( fn ) + + // Wrap jQuery.readyException in a function so that the lookup + // happens at the time of error handling instead of callback + // registration. + .catch( function( error ) { + jQuery.readyException( error ); + } ); + + return this; +}; + +jQuery.extend( { + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + } +} ); + +jQuery.ready.then = readyList.then; + +// The ready event handler and self cleanup method +function completed() { + document.removeEventListener( "DOMContentLoaded", completed ); + window.removeEventListener( "load", completed ); + jQuery.ready(); +} + +// Catch cases where $(document).ready() is called +// after the browser event has already occurred. +// Support: IE <=9 - 10 only +// Older IE sometimes signals "interactive" too soon +if ( document.readyState === "complete" || + ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { + + // Handle it asynchronously to allow scripts the opportunity to delay ready + window.setTimeout( jQuery.ready ); + +} else { + + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed ); +} + + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + len = elems.length, + bulk = key == null; + + // Sets many values + if ( toType( key ) === "object" ) { + chainable = true; + for ( i in key ) { + access( elems, fn, i, key[ i ], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, _key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < len; i++ ) { + fn( + elems[ i ], key, raw ? + value : + value.call( elems[ i ], i, fn( elems[ i ], key ) ) + ); + } + } + } + + if ( chainable ) { + return elems; + } + + // Gets + if ( bulk ) { + return fn.call( elems ); + } + + return len ? fn( elems[ 0 ], key ) : emptyGet; +}; + + +// Matches dashed string for camelizing +var rmsPrefix = /^-ms-/, + rdashAlpha = /-([a-z])/g; + +// Used by camelCase as callback to replace() +function fcamelCase( _all, letter ) { + return letter.toUpperCase(); +} + +// Convert dashed to camelCase; used by the css and data modules +// Support: IE <=9 - 11, Edge 12 - 15 +// Microsoft forgot to hump their vendor prefix (#9572) +function camelCase( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); +} +var acceptData = function( owner ) { + + // Accepts only: + // - Node + // - Node.ELEMENT_NODE + // - Node.DOCUMENT_NODE + // - Object + // - Any + return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); +}; + + + + +function Data() { + this.expando = jQuery.expando + Data.uid++; +} + +Data.uid = 1; + +Data.prototype = { + + cache: function( owner ) { + + // Check if the owner object already has a cache + var value = owner[ this.expando ]; + + // If not, create one + if ( !value ) { + value = {}; + + // We can accept data for non-element nodes in modern browsers, + // but we should not, see #8335. + // Always return an empty object. + if ( acceptData( owner ) ) { + + // If it is a node unlikely to be stringify-ed or looped over + // use plain assignment + if ( owner.nodeType ) { + owner[ this.expando ] = value; + + // Otherwise secure it in a non-enumerable property + // configurable must be true to allow the property to be + // deleted when data is removed + } else { + Object.defineProperty( owner, this.expando, { + value: value, + configurable: true + } ); + } + } + } + + return value; + }, + set: function( owner, data, value ) { + var prop, + cache = this.cache( owner ); + + // Handle: [ owner, key, value ] args + // Always use camelCase key (gh-2257) + if ( typeof data === "string" ) { + cache[ camelCase( data ) ] = value; + + // Handle: [ owner, { properties } ] args + } else { + + // Copy the properties one-by-one to the cache object + for ( prop in data ) { + cache[ camelCase( prop ) ] = data[ prop ]; + } + } + return cache; + }, + get: function( owner, key ) { + return key === undefined ? + this.cache( owner ) : + + // Always use camelCase key (gh-2257) + owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; + }, + access: function( owner, key, value ) { + + // In cases where either: + // + // 1. No key was specified + // 2. A string key was specified, but no value provided + // + // Take the "read" path and allow the get method to determine + // which value to return, respectively either: + // + // 1. The entire cache object + // 2. The data stored at the key + // + if ( key === undefined || + ( ( key && typeof key === "string" ) && value === undefined ) ) { + + return this.get( owner, key ); + } + + // When the key is not a string, or both a key and value + // are specified, set or extend (existing objects) with either: + // + // 1. An object of properties + // 2. A key and value + // + this.set( owner, key, value ); + + // Since the "set" path can have two possible entry points + // return the expected data based on which path was taken[*] + return value !== undefined ? value : key; + }, + remove: function( owner, key ) { + var i, + cache = owner[ this.expando ]; + + if ( cache === undefined ) { + return; + } + + if ( key !== undefined ) { + + // Support array or space separated string of keys + if ( Array.isArray( key ) ) { + + // If key is an array of keys... + // We always set camelCase keys, so remove that. + key = key.map( camelCase ); + } else { + key = camelCase( key ); + + // If a key with the spaces exists, use it. + // Otherwise, create an array by matching non-whitespace + key = key in cache ? + [ key ] : + ( key.match( rnothtmlwhite ) || [] ); + } + + i = key.length; + + while ( i-- ) { + delete cache[ key[ i ] ]; + } + } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + + // Support: Chrome <=35 - 45 + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) + if ( owner.nodeType ) { + owner[ this.expando ] = undefined; + } else { + delete owner[ this.expando ]; + } + } + }, + hasData: function( owner ) { + var cache = owner[ this.expando ]; + return cache !== undefined && !jQuery.isEmptyObject( cache ); + } +}; +var dataPriv = new Data(); + +var dataUser = new Data(); + + + +// Implementation Summary +// +// 1. Enforce API surface and semantic compatibility with 1.9.x branch +// 2. Improve the module's maintainability by reducing the storage +// paths to a single mechanism. +// 3. Use the same single mechanism to support "private" and "user" data. +// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) +// 5. Avoid exposing implementation details on user objects (eg. expando properties) +// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /[A-Z]/g; + +function getData( data ) { + if ( data === "true" ) { + return true; + } + + if ( data === "false" ) { + return false; + } + + if ( data === "null" ) { + return null; + } + + // Only convert to a number if it doesn't change the string + if ( data === +data + "" ) { + return +data; + } + + if ( rbrace.test( data ) ) { + return JSON.parse( data ); + } + + return data; +} + +function dataAttr( elem, key, data ) { + var name; + + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = getData( data ); + } catch ( e ) {} + + // Make sure we set the data so it isn't changed later + dataUser.set( elem, key, data ); + } else { + data = undefined; + } + } + return data; +} + +jQuery.extend( { + hasData: function( elem ) { + return dataUser.hasData( elem ) || dataPriv.hasData( elem ); + }, + + data: function( elem, name, data ) { + return dataUser.access( elem, name, data ); + }, + + removeData: function( elem, name ) { + dataUser.remove( elem, name ); + }, + + // TODO: Now that all calls to _data and _removeData have been replaced + // with direct calls to dataPriv methods, these can be deprecated. + _data: function( elem, name, data ) { + return dataPriv.access( elem, name, data ); + }, + + _removeData: function( elem, name ) { + dataPriv.remove( elem, name ); + } +} ); + +jQuery.fn.extend( { + data: function( key, value ) { + var i, name, data, + elem = this[ 0 ], + attrs = elem && elem.attributes; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = dataUser.get( elem ); + + if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE 11 only + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = camelCase( name.slice( 5 ) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + dataPriv.set( elem, "hasDataAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each( function() { + dataUser.set( this, key ); + } ); + } + + return access( this, function( value ) { + var data; + + // The calling jQuery object (element matches) is not empty + // (and therefore has an element appears at this[ 0 ]) and the + // `value` parameter was not undefined. An empty jQuery object + // will result in `undefined` for elem = this[ 0 ] which will + // throw an exception if an attempt to read a data cache is made. + if ( elem && value === undefined ) { + + // Attempt to get data from the cache + // The key will always be camelCased in Data + data = dataUser.get( elem, key ); + if ( data !== undefined ) { + return data; + } + + // Attempt to "discover" the data in + // HTML5 custom data-* attrs + data = dataAttr( elem, key ); + if ( data !== undefined ) { + return data; + } + + // We tried really hard, but the data doesn't exist. + return; + } + + // Set the data... + this.each( function() { + + // We always store the camelCased key + dataUser.set( this, key, value ); + } ); + }, null, value, arguments.length > 1, null, true ); + }, + + removeData: function( key ) { + return this.each( function() { + dataUser.remove( this, key ); + } ); + } +} ); + + +jQuery.extend( { + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = dataPriv.get( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || Array.isArray( data ) ) { + queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // Clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // Not public - generate a queueHooks object, or return the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { + empty: jQuery.Callbacks( "once memory" ).add( function() { + dataPriv.remove( elem, [ type + "queue", key ] ); + } ) + } ); + } +} ); + +jQuery.fn.extend( { + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[ 0 ], type ); + } + + return data === undefined ? + this : + this.each( function() { + var queue = jQuery.queue( this, type, data ); + + // Ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + } ); + }, + dequeue: function( type ) { + return this.each( function() { + jQuery.dequeue( this, type ); + } ); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +} ); +var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; + +var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); + + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var documentElement = document.documentElement; + + + + var isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ); + }, + composed = { composed: true }; + + // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only + // Check attachment across shadow DOM boundaries when possible (gh-3504) + // Support: iOS 10.0-10.2 only + // Early iOS 10 versions support `attachShadow` but not `getRootNode`, + // leading to errors. We need to check for `getRootNode`. + if ( documentElement.getRootNode ) { + isAttached = function( elem ) { + return jQuery.contains( elem.ownerDocument, elem ) || + elem.getRootNode( composed ) === elem.ownerDocument; + }; + } +var isHiddenWithinTree = function( elem, el ) { + + // isHiddenWithinTree might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + + // Inline style trumps all + return elem.style.display === "none" || + elem.style.display === "" && + + // Otherwise, check computed style + // Support: Firefox <=43 - 45 + // Disconnected elements can have computed display: none, so first confirm that elem is + // in the document. + isAttached( elem ) && + + jQuery.css( elem, "display" ) === "none"; + }; + + + +function adjustCSS( elem, prop, valueParts, tween ) { + var adjusted, scale, + maxIterations = 20, + currentValue = tween ? + function() { + return tween.cur(); + } : + function() { + return jQuery.css( elem, prop, "" ); + }, + initial = currentValue(), + unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + initialInUnit = elem.nodeType && + ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && + rcssNum.exec( jQuery.css( elem, prop ) ); + + if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { + + // Support: Firefox <=54 + // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) + initial = initial / 2; + + // Trust units reported by jQuery.css + unit = unit || initialInUnit[ 3 ]; + + // Iteratively approximate from a nonzero starting point + initialInUnit = +initial || 1; + + while ( maxIterations-- ) { + + // Evaluate and update our best guess (doubling guesses that zero out). + // Finish if the scale equals or crosses 1 (making the old*new product non-positive). + jQuery.style( elem, prop, initialInUnit + unit ); + if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { + maxIterations = 0; + } + initialInUnit = initialInUnit / scale; + + } + + initialInUnit = initialInUnit * 2; + jQuery.style( elem, prop, initialInUnit + unit ); + + // Make sure we update the tween properties later on + valueParts = valueParts || []; + } + + if ( valueParts ) { + initialInUnit = +initialInUnit || +initial || 0; + + // Apply relative offset (+=/-=) if specified + adjusted = valueParts[ 1 ] ? + initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : + +valueParts[ 2 ]; + if ( tween ) { + tween.unit = unit; + tween.start = initialInUnit; + tween.end = adjusted; + } + } + return adjusted; +} + + +var defaultDisplayMap = {}; + +function getDefaultDisplay( elem ) { + var temp, + doc = elem.ownerDocument, + nodeName = elem.nodeName, + display = defaultDisplayMap[ nodeName ]; + + if ( display ) { + return display; + } + + temp = doc.body.appendChild( doc.createElement( nodeName ) ); + display = jQuery.css( temp, "display" ); + + temp.parentNode.removeChild( temp ); + + if ( display === "none" ) { + display = "block"; + } + defaultDisplayMap[ nodeName ] = display; + + return display; +} + +function showHide( elements, show ) { + var display, elem, + values = [], + index = 0, + length = elements.length; + + // Determine new display value for elements that need to change + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + display = elem.style.display; + if ( show ) { + + // Since we force visibility upon cascade-hidden elements, an immediate (and slow) + // check is required in this first loop unless we have a nonempty display value (either + // inline or about-to-be-restored) + if ( display === "none" ) { + values[ index ] = dataPriv.get( elem, "display" ) || null; + if ( !values[ index ] ) { + elem.style.display = ""; + } + } + if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { + values[ index ] = getDefaultDisplay( elem ); + } + } else { + if ( display !== "none" ) { + values[ index ] = "none"; + + // Remember what we're overwriting + dataPriv.set( elem, "display", display ); + } + } + } + + // Set the display of the elements in a second loop to avoid constant reflow + for ( index = 0; index < length; index++ ) { + if ( values[ index ] != null ) { + elements[ index ].style.display = values[ index ]; + } + } + + return elements; +} + +jQuery.fn.extend( { + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each( function() { + if ( isHiddenWithinTree( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + } ); + } +} ); +var rcheckableType = ( /^(?:checkbox|radio)$/i ); + +var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); + +var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); + + + +( function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement( "div" ) ), + input = document.createElement( "input" ); + + // Support: Android 4.0 - 4.3 only + // Check state lost if the name is set (#11217) + // Support: Windows Web Apps (WWA) + // `name` and `type` must use .setAttribute for WWA (#14901) + input.setAttribute( "type", "radio" ); + input.setAttribute( "checked", "checked" ); + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + + // Support: Android <=4.1 only + // Older WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE <=11 only + // Make sure textarea (and checkbox) defaultValue is properly cloned + div.innerHTML = ""; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // Support: IE <=9 only + // IE <=9 replaces "; + support.option = !!div.lastChild; +} )(); + + +// We have to close these tags to support XHTML (#13200) +var wrapMap = { + + // XHTML parsers do not magically insert elements in the + // same way that tag soup parsers do. So we cannot shorten + // this by omitting or other required elements. + thead: [ 1, "", "
" ], + col: [ 2, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + + _default: [ 0, "", "" ] +}; + +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// Support: IE <=9 only +if ( !support.option ) { + wrapMap.optgroup = wrapMap.option = [ 1, "" ]; +} + + +function getAll( context, tag ) { + + // Support: IE <=9 - 11 only + // Use typeof to avoid zero-argument method invocation on host objects (#15151) + var ret; + + if ( typeof context.getElementsByTagName !== "undefined" ) { + ret = context.getElementsByTagName( tag || "*" ); + + } else if ( typeof context.querySelectorAll !== "undefined" ) { + ret = context.querySelectorAll( tag || "*" ); + + } else { + ret = []; + } + + if ( tag === undefined || tag && nodeName( context, tag ) ) { + return jQuery.merge( [ context ], ret ); + } + + return ret; +} + + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + dataPriv.set( + elems[ i ], + "globalEval", + !refElements || dataPriv.get( refElements[ i ], "globalEval" ) + ); + } +} + + +var rhtml = /<|&#?\w+;/; + +function buildFragment( elems, context, scripts, selection, ignored ) { + var elem, tmp, tag, wrap, attached, j, + fragment = context.createDocumentFragment(), + nodes = [], + i = 0, + l = elems.length; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( toType( elem ) === "object" ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; + + // Descend through wrappers to the right content + j = wrap[ 0 ]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( nodes, tmp.childNodes ); + + // Remember the top-level container + tmp = fragment.firstChild; + + // Ensure the created nodes are orphaned (#12392) + tmp.textContent = ""; + } + } + } + + // Remove wrapper from fragment + fragment.textContent = ""; + + i = 0; + while ( ( elem = nodes[ i++ ] ) ) { + + // Skip elements already in the context collection (trac-4087) + if ( selection && jQuery.inArray( elem, selection ) > -1 ) { + if ( ignored ) { + ignored.push( elem ); + } + continue; + } + + attached = isAttached( elem ); + + // Append to fragment + tmp = getAll( fragment.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( attached ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( ( elem = tmp[ j++ ] ) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + return fragment; +} + + +var + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +// Support: IE <=9 - 11+ +// focus() and blur() are asynchronous, except when they are no-op. +// So expect focus to be synchronous when the element is already active, +// and blur to be synchronous when the element is not already active. +// (focus and blur are always synchronous in other supported browsers, +// this just defines when we can count on it). +function expectSync( elem, type ) { + return ( elem === safeActiveElement() ) === ( type === "focus" ); +} + +// Support: IE <=9 only +// Accessing document.activeElement can throw unexpectedly +// https://bugs.jquery.com/ticket/13393 +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +function on( elem, types, selector, data, fn, one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + on( elem, type, selector, data, types[ type ], one ); + } + return elem; + } + + if ( data == null && fn == null ) { + + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return elem; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return elem.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + } ); +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.get( elem ); + + // Only attach events to objects that accept data + if ( !acceptData( elem ) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Ensure that invalid selectors throw exceptions at attach time + // Evaluate against documentElement in case elem is a non-element node (e.g., document) + if ( selector ) { + jQuery.find.matchesSelector( documentElement, selector ); + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !( events = elemData.events ) ) { + events = elemData.events = Object.create( null ); + } + if ( !( eventHandle = elemData.handle ) ) { + eventHandle = elemData.handle = function( e ) { + + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + jQuery.event.dispatch.apply( elem, arguments ) : undefined; + }; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend( { + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join( "." ) + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !( handlers = events[ type ] ) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener if the special events handler returns false + if ( !special.setup || + special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); + + if ( !elemData || !( events = elemData.events ) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[ t ] ) || []; + type = origType = tmp[ 1 ]; + namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[ 2 ] && + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || + selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || + special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove data and the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + dataPriv.remove( elem, "handle events" ); + } + }, + + dispatch: function( nativeEvent ) { + + var i, j, ret, matched, handleObj, handlerQueue, + args = new Array( arguments.length ), + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( nativeEvent ), + + handlers = ( + dataPriv.get( this, "events" ) || Object.create( null ) + )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[ 0 ] = event; + + for ( i = 1; i < arguments.length; i++ ) { + args[ i ] = arguments[ i ]; + } + + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( ( handleObj = matched.handlers[ j++ ] ) && + !event.isImmediatePropagationStopped() ) { + + // If the event is namespaced, then each handler is only invoked if it is + // specially universal or its namespaces are a superset of the event's. + if ( !event.rnamespace || handleObj.namespace === false || + event.rnamespace.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || + handleObj.handler ).apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( ( event.result = ret ) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var i, handleObj, sel, matchedHandlers, matchedSelectors, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + if ( delegateCount && + + // Support: IE <=9 + // Black-hole SVG instance trees (trac-13180) + cur.nodeType && + + // Support: Firefox <=42 + // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) + // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click + // Support: IE 11 only + // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) + !( event.type === "click" && event.button >= 1 ) ) { + + for ( ; cur !== this; cur = cur.parentNode || this ) { + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { + matchedHandlers = []; + matchedSelectors = {}; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matchedSelectors[ sel ] === undefined ) { + matchedSelectors[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) > -1 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matchedSelectors[ sel ] ) { + matchedHandlers.push( handleObj ); + } + } + if ( matchedHandlers.length ) { + handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); + } + } + } + } + + // Add the remaining (directly-bound) handlers + cur = this; + if ( delegateCount < handlers.length ) { + handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); + } + + return handlerQueue; + }, + + addProp: function( name, hook ) { + Object.defineProperty( jQuery.Event.prototype, name, { + enumerable: true, + configurable: true, + + get: isFunction( hook ) ? + function() { + if ( this.originalEvent ) { + return hook( this.originalEvent ); + } + } : + function() { + if ( this.originalEvent ) { + return this.originalEvent[ name ]; + } + }, + + set: function( value ) { + Object.defineProperty( this, name, { + enumerable: true, + configurable: true, + writable: true, + value: value + } ); + } + } ); + }, + + fix: function( originalEvent ) { + return originalEvent[ jQuery.expando ] ? + originalEvent : + new jQuery.Event( originalEvent ); + }, + + special: { + load: { + + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + click: { + + // Utilize native event to ensure correct state for checkable inputs + setup: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Claim the first handler + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + // dataPriv.set( el, "click", ... ) + leverageNative( el, "click", returnTrue ); + } + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function( data ) { + + // For mutual compressibility with _default, replace `this` access with a local var. + // `|| data` is dead code meant only to preserve the variable through minification. + var el = this || data; + + // Force setup before triggering a click + if ( rcheckableType.test( el.type ) && + el.click && nodeName( el, "input" ) ) { + + leverageNative( el, "click" ); + } + + // Return non-false to allow normal event-path propagation + return true; + }, + + // For cross-browser consistency, suppress native .click() on links + // Also prevent it if we're currently inside a leveraged native-event stack + _default: function( event ) { + var target = event.target; + return rcheckableType.test( target.type ) && + target.click && nodeName( target, "input" ) && + dataPriv.get( target, "click" ) || + nodeName( target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + } +}; + +// Ensure the presence of an event listener that handles manually-triggered +// synthetic events by interrupting progress until reinvoked in response to +// *native* events that it fires directly, ensuring that state changes have +// already occurred before other listeners are invoked. +function leverageNative( el, type, expectSync ) { + + // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add + if ( !expectSync ) { + if ( dataPriv.get( el, type ) === undefined ) { + jQuery.event.add( el, type, returnTrue ); + } + return; + } + + // Register the controller as a special universal handler for all event namespaces + dataPriv.set( el, type, false ); + jQuery.event.add( el, type, { + namespace: false, + handler: function( event ) { + var notAsync, result, + saved = dataPriv.get( this, type ); + + if ( ( event.isTrigger & 1 ) && this[ type ] ) { + + // Interrupt processing of the outer synthetic .trigger()ed event + // Saved data should be false in such cases, but might be a leftover capture object + // from an async native handler (gh-4350) + if ( !saved.length ) { + + // Store arguments for use when handling the inner native event + // There will always be at least one argument (an event object), so this array + // will not be confused with a leftover capture object. + saved = slice.call( arguments ); + dataPriv.set( this, type, saved ); + + // Trigger the native event and capture its result + // Support: IE <=9 - 11+ + // focus() and blur() are asynchronous + notAsync = expectSync( this, type ); + this[ type ](); + result = dataPriv.get( this, type ); + if ( saved !== result || notAsync ) { + dataPriv.set( this, type, false ); + } else { + result = {}; + } + if ( saved !== result ) { + + // Cancel the outer synthetic event + event.stopImmediatePropagation(); + event.preventDefault(); + return result.value; + } + + // If this is an inner synthetic event for an event with a bubbling surrogate + // (focus or blur), assume that the surrogate already propagated from triggering the + // native event and prevent that from happening again here. + // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the + // bubbling surrogate propagates *after* the non-bubbling base), but that seems + // less bad than duplication. + } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { + event.stopPropagation(); + } + + // If this is a native event triggered above, everything is now in order + // Fire an inner synthetic event with the original arguments + } else if ( saved.length ) { + + // ...and capture the result + dataPriv.set( this, type, { + value: jQuery.event.trigger( + + // Support: IE <=9 - 11+ + // Extend with the prototype to reset the above stopImmediatePropagation() + jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), + saved.slice( 1 ), + this + ) + } ); + + // Abort handling of the native event + event.stopImmediatePropagation(); + } + } + } ); +} + +jQuery.removeEvent = function( elem, type, handle ) { + + // This "if" is needed for plain objects + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle ); + } +}; + +jQuery.Event = function( src, props ) { + + // Allow instantiation without the 'new' keyword + if ( !( this instanceof jQuery.Event ) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + + // Support: Android <=2.3 only + src.returnValue === false ? + returnTrue : + returnFalse; + + // Create target properties + // Support: Safari <=6 - 7 only + // Target should not be a text node (#504, #13143) + this.target = ( src.target && src.target.nodeType === 3 ) ? + src.target.parentNode : + src.target; + + this.currentTarget = src.currentTarget; + this.relatedTarget = src.relatedTarget; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + constructor: jQuery.Event, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + isSimulated: false, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + + if ( e && !this.isSimulated ) { + e.preventDefault(); + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopPropagation(); + } + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && !this.isSimulated ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Includes all common event props including KeyEvent and MouseEvent specific props +jQuery.each( { + altKey: true, + bubbles: true, + cancelable: true, + changedTouches: true, + ctrlKey: true, + detail: true, + eventPhase: true, + metaKey: true, + pageX: true, + pageY: true, + shiftKey: true, + view: true, + "char": true, + code: true, + charCode: true, + key: true, + keyCode: true, + button: true, + buttons: true, + clientX: true, + clientY: true, + offsetX: true, + offsetY: true, + pointerId: true, + pointerType: true, + screenX: true, + screenY: true, + targetTouches: true, + toElement: true, + touches: true, + + which: function( event ) { + var button = event.button; + + // Add which for key events + if ( event.which == null && rkeyEvent.test( event.type ) ) { + return event.charCode != null ? event.charCode : event.keyCode; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { + if ( button & 1 ) { + return 1; + } + + if ( button & 2 ) { + return 3; + } + + if ( button & 4 ) { + return 2; + } + + return 0; + } + + return event.which; + } +}, jQuery.event.addProp ); + +jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { + jQuery.event.special[ type ] = { + + // Utilize native event if possible so blur/focus sequence is correct + setup: function() { + + // Claim the first handler + // dataPriv.set( this, "focus", ... ) + // dataPriv.set( this, "blur", ... ) + leverageNative( this, type, expectSync ); + + // Return false to allow normal processing in the caller + return false; + }, + trigger: function() { + + // Force setup before trigger + leverageNative( this, type ); + + // Return non-false to allow normal event-path propagation + return true; + }, + + delegateType: delegateType + }; +} ); + +// Create mouseenter/leave events using mouseover/out and event-time checks +// so that event delegation works in jQuery. +// Do the same for pointerenter/pointerleave and pointerover/pointerout +// +// Support: Safari 7 only +// Safari sends mouseenter too often; see: +// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 +// for the description of the bug (it existed in older Chrome versions as well). +jQuery.each( { + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mouseenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +} ); + +jQuery.fn.extend( { + + on: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn ); + }, + one: function( types, selector, data, fn ) { + return on( this, types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? + handleObj.origType + "." + handleObj.namespace : + handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each( function() { + jQuery.event.remove( this, types, fn, selector ); + } ); + } +} ); + + +var + + // Support: IE <=10 - 11, Edge 12 - 13 only + // In IE/Edge using regex groups here causes severe slowdowns. + // See https://connect.microsoft.com/IE/feedback/details/1736512/ + rnoInnerhtml = /\s*$/g; + +// Prefer a tbody over its parent table for containing new rows +function manipulationTarget( elem, content ) { + if ( nodeName( elem, "table" ) && + nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { + + return jQuery( elem ).children( "tbody" )[ 0 ] || elem; + } + + return elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { + elem.type = elem.type.slice( 5 ); + } else { + elem.removeAttribute( "type" ); + } + + return elem; +} + +function cloneCopyEvent( src, dest ) { + var i, l, type, pdataOld, udataOld, udataCur, events; + + if ( dest.nodeType !== 1 ) { + return; + } + + // 1. Copy private data: events, handlers, etc. + if ( dataPriv.hasData( src ) ) { + pdataOld = dataPriv.get( src ); + events = pdataOld.events; + + if ( events ) { + dataPriv.remove( dest, "handle events" ); + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + } + + // 2. Copy user data + if ( dataUser.hasData( src ) ) { + udataOld = dataUser.access( src ); + udataCur = jQuery.extend( {}, udataOld ); + + dataUser.set( dest, udataCur ); + } +} + +// Fix IE bugs, see support tests +function fixInput( src, dest ) { + var nodeName = dest.nodeName.toLowerCase(); + + // Fails to persist the checked state of a cloned checkbox or radio button. + if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + dest.checked = src.checked; + + // Fails to return the selected option to the default selected state when cloning options + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +function domManip( collection, args, callback, ignored ) { + + // Flatten any nested arrays + args = flat( args ); + + var fragment, first, scripts, hasScripts, node, doc, + i = 0, + l = collection.length, + iNoClone = l - 1, + value = args[ 0 ], + valueIsFunction = isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( valueIsFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return collection.each( function( index ) { + var self = collection.eq( index ); + if ( valueIsFunction ) { + args[ 0 ] = value.call( this, index, self.html() ); + } + domManip( self, args, callback, ignored ); + } ); + } + + if ( l ) { + fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + // Require either new content or an interest in ignored elements to invoke the callback + if ( first || ignored ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item + // instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + + // Support: Android <=4.0 only, PhantomJS 1 only + // push.apply(_, arraylike) throws on ancient WebKit + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( collection[ i ], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !dataPriv.access( node, "globalEval" ) && + jQuery.contains( doc, node ) ) { + + if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { + + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl && !node.noModule ) { + jQuery._evalUrl( node.src, { + nonce: node.nonce || node.getAttribute( "nonce" ) + }, doc ); + } + } else { + DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); + } + } + } + } + } + } + + return collection; +} + +function remove( elem, selector, keepData ) { + var node, + nodes = selector ? jQuery.filter( selector, elem ) : elem, + i = 0; + + for ( ; ( node = nodes[ i ] ) != null; i++ ) { + if ( !keepData && node.nodeType === 1 ) { + jQuery.cleanData( getAll( node ) ); + } + + if ( node.parentNode ) { + if ( keepData && isAttached( node ) ) { + setGlobalEval( getAll( node, "script" ) ); + } + node.parentNode.removeChild( node ); + } + } + + return elem; +} + +jQuery.extend( { + htmlPrefilter: function( html ) { + return html; + }, + + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var i, l, srcElements, destElements, + clone = elem.cloneNode( true ), + inPage = isAttached( elem ); + + // Fix IE cloning issues + if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && + !jQuery.isXMLDoc( elem ) ) { + + // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + fixInput( srcElements[ i ], destElements[ i ] ); + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0, l = srcElements.length; i < l; i++ ) { + cloneCopyEvent( srcElements[ i ], destElements[ i ] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + // Return the cloned set + return clone; + }, + + cleanData: function( elems ) { + var data, elem, type, + special = jQuery.event.special, + i = 0; + + for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { + if ( acceptData( elem ) ) { + if ( ( data = elem[ dataPriv.expando ] ) ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataPriv.expando ] = undefined; + } + if ( elem[ dataUser.expando ] ) { + + // Support: Chrome <=35 - 45+ + // Assign undefined instead of using delete, see Data#remove + elem[ dataUser.expando ] = undefined; + } + } + } + } +} ); + +jQuery.fn.extend( { + detach: function( selector ) { + return remove( this, selector, true ); + }, + + remove: function( selector ) { + return remove( this, selector ); + }, + + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().each( function() { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + this.textContent = value; + } + } ); + }, null, value, arguments.length ); + }, + + append: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + } ); + }, + + prepend: function() { + return domManip( this, arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + } ); + }, + + before: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + } ); + }, + + after: function() { + return domManip( this, arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + } ); + }, + + empty: function() { + var elem, + i = 0; + + for ( ; ( elem = this[ i ] ) != null; i++ ) { + if ( elem.nodeType === 1 ) { + + // Prevent memory leaks + jQuery.cleanData( getAll( elem, false ) ); + + // Remove any remaining nodes + elem.textContent = ""; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + } ); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined && elem.nodeType === 1 ) { + return elem.innerHTML; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { + + value = jQuery.htmlPrefilter( value ); + + try { + for ( ; i < l; i++ ) { + elem = this[ i ] || {}; + + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch ( e ) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var ignored = []; + + // Make the changes, replacing each non-ignored context element with the new content + return domManip( this, arguments, function( elem ) { + var parent = this.parentNode; + + if ( jQuery.inArray( this, ignored ) < 0 ) { + jQuery.cleanData( getAll( this ) ); + if ( parent ) { + parent.replaceChild( elem, this ); + } + } + + // Force callback invocation + }, ignored ); + } +} ); + +jQuery.each( { + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1, + i = 0; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone( true ); + jQuery( insert[ i ] )[ original ]( elems ); + + // Support: Android <=4.0 only, PhantomJS 1 only + // .get() because push.apply(_, arraylike) throws on ancient WebKit + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +} ); +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + +var getStyles = function( elem ) { + + // Support: IE <=11 only, Firefox <=30 (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + var view = elem.ownerDocument.defaultView; + + if ( !view || !view.opener ) { + view = window; + } + + return view.getComputedStyle( elem ); + }; + +var swap = function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); + + + +( function() { + + // Executing both pixelPosition & boxSizingReliable tests require only one layout + // so they're executed at the same time to save the second computation. + function computeStyleTests() { + + // This is a singleton, we need to execute it only once + if ( !div ) { + return; + } + + container.style.cssText = "position:absolute;left:-11111px;width:60px;" + + "margin-top:1px;padding:0;border:0"; + div.style.cssText = + "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + + "margin:auto;border:1px;padding:1px;" + + "width:60%;top:1%"; + documentElement.appendChild( container ).appendChild( div ); + + var divStyle = window.getComputedStyle( div ); + pixelPositionVal = divStyle.top !== "1%"; + + // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 + reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; + + // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 + // Some styles come back with percentage values, even though they shouldn't + div.style.right = "60%"; + pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; + + // Support: IE 9 - 11 only + // Detect misreporting of content dimensions for box-sizing:border-box elements + boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; + + // Support: IE 9 only + // Detect overflow:scroll screwiness (gh-3699) + // Support: Chrome <=64 + // Don't get tricked when zoom affects offsetWidth (gh-4029) + div.style.position = "absolute"; + scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; + + documentElement.removeChild( container ); + + // Nullify the div so it wouldn't be stored in the memory and + // it will also be a sign that checks already performed + div = null; + } + + function roundPixelMeasures( measure ) { + return Math.round( parseFloat( measure ) ); + } + + var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, + reliableTrDimensionsVal, reliableMarginLeftVal, + container = document.createElement( "div" ), + div = document.createElement( "div" ); + + // Finish early in limited (non-browser) environments + if ( !div.style ) { + return; + } + + // Support: IE <=9 - 11 only + // Style of cloned element affects source element cloned (#8908) + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + jQuery.extend( support, { + boxSizingReliable: function() { + computeStyleTests(); + return boxSizingReliableVal; + }, + pixelBoxStyles: function() { + computeStyleTests(); + return pixelBoxStylesVal; + }, + pixelPosition: function() { + computeStyleTests(); + return pixelPositionVal; + }, + reliableMarginLeft: function() { + computeStyleTests(); + return reliableMarginLeftVal; + }, + scrollboxSize: function() { + computeStyleTests(); + return scrollboxSizeVal; + }, + + // Support: IE 9 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Behavior in IE 9 is more subtle than in newer versions & it passes + // some versions of this test; make sure not to make it pass there! + reliableTrDimensions: function() { + var table, tr, trChild, trStyle; + if ( reliableTrDimensionsVal == null ) { + table = document.createElement( "table" ); + tr = document.createElement( "tr" ); + trChild = document.createElement( "div" ); + + table.style.cssText = "position:absolute;left:-11111px"; + tr.style.height = "1px"; + trChild.style.height = "9px"; + + documentElement + .appendChild( table ) + .appendChild( tr ) + .appendChild( trChild ); + + trStyle = window.getComputedStyle( tr ); + reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; + + documentElement.removeChild( table ); + } + return reliableTrDimensionsVal; + } + } ); +} )(); + + +function curCSS( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + + // Support: Firefox 51+ + // Retrieving style before computed somehow + // fixes an issue with getting wrong values + // on detached elements + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is needed for: + // .css('filter') (IE 9 only, #12537) + // .css('--customProperty) (#3144) + if ( computed ) { + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !isAttached( elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Android Browser returns percentage for some values, + // but width seems to be reliably pixels. + // This is against the CSSOM draft spec: + // https://drafts.csswg.org/cssom/#resolved-values + if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret !== undefined ? + + // Support: IE <=9 - 11 only + // IE returns zIndex value as an integer. + ret + "" : + ret; +} + + +function addGetHookIf( conditionFn, hookFn ) { + + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + if ( conditionFn() ) { + + // Hook not needed (or it's not possible to use it due + // to missing dependency), remove it. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + return ( this.get = hookFn ).apply( this, arguments ); + } + }; +} + + +var cssPrefixes = [ "Webkit", "Moz", "ms" ], + emptyStyle = document.createElement( "div" ).style, + vendorProps = {}; + +// Return a vendor-prefixed property or undefined +function vendorPropName( name ) { + + // Check for vendor prefixed names + var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in emptyStyle ) { + return name; + } + } +} + +// Return a potentially-mapped jQuery.cssProps or vendor prefixed property +function finalPropName( name ) { + var final = jQuery.cssProps[ name ] || vendorProps[ name ]; + + if ( final ) { + return final; + } + if ( name in emptyStyle ) { + return name; + } + return vendorProps[ name ] = vendorPropName( name ) || name; +} + + +var + + // Swappable if display is none or starts with table + // except "table", "table-cell", or "table-caption" + // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rcustomProp = /^--/, + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }; + +function setPositiveNumber( _elem, value, subtract ) { + + // Any relative (+/-) values have already been + // normalized at this point + var matches = rcssNum.exec( value ); + return matches ? + + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : + value; +} + +function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { + var i = dimension === "width" ? 1 : 0, + extra = 0, + delta = 0; + + // Adjustment may not be necessary + if ( box === ( isBorderBox ? "border" : "content" ) ) { + return 0; + } + + for ( ; i < 4; i += 2 ) { + + // Both box models exclude margin + if ( box === "margin" ) { + delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); + } + + // If we get here with a content-box, we're seeking "padding" or "border" or "margin" + if ( !isBorderBox ) { + + // Add padding + delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // For "border" or "margin", add border + if ( box !== "padding" ) { + delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + + // But still keep track of it otherwise + } else { + extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + + // If we get here with a border-box (content + padding + border), we're seeking "content" or + // "padding" or "margin" + } else { + + // For "content", subtract padding + if ( box === "content" ) { + delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // For "content" or "padding", subtract border + if ( box !== "margin" ) { + delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + // Account for positive content-box scroll gutter when requested by providing computedVal + if ( !isBorderBox && computedVal >= 0 ) { + + // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border + // Assuming integer scroll gutter, subtract the rest and round down + delta += Math.max( 0, Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + computedVal - + delta - + extra - + 0.5 + + // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter + // Use an explicit zero to avoid NaN (gh-3964) + ) ) || 0; + } + + return delta; +} + +function getWidthOrHeight( elem, dimension, extra ) { + + // Start with computed style + var styles = getStyles( elem ), + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). + // Fake content-box until we know it's needed to know the true value. + boxSizingNeeded = !support.boxSizingReliable() || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + valueIsBorderBox = isBorderBox, + + val = curCSS( elem, dimension, styles ), + offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); + + // Support: Firefox <=54 + // Return a confounding non-pixel value or feign ignorance, as appropriate. + if ( rnumnonpx.test( val ) ) { + if ( !extra ) { + return val; + } + val = "auto"; + } + + + // Support: IE 9 - 11 only + // Use offsetWidth/offsetHeight for when box sizing is unreliable. + // In those cases, the computed value can be trusted to be border-box. + if ( ( !support.boxSizingReliable() && isBorderBox || + + // Support: IE 10 - 11+, Edge 15 - 18+ + // IE/Edge misreport `getComputedStyle` of table rows with width/height + // set in CSS while `offset*` properties report correct values. + // Interestingly, in some cases IE 9 doesn't suffer from this issue. + !support.reliableTrDimensions() && nodeName( elem, "tr" ) || + + // Fall back to offsetWidth/offsetHeight when value is "auto" + // This happens for inline elements with no explicit setting (gh-3571) + val === "auto" || + + // Support: Android <=4.1 - 4.3 only + // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) + !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && + + // Make sure the element is visible & connected + elem.getClientRects().length ) { + + isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // Where available, offsetWidth/offsetHeight approximate border box dimensions. + // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the + // retrieved value as a content box dimension. + valueIsBorderBox = offsetProp in elem; + if ( valueIsBorderBox ) { + val = elem[ offsetProp ]; + } + } + + // Normalize "" and auto + val = parseFloat( val ) || 0; + + // Adjust for the element's box model + return ( val + + boxModelAdjustment( + elem, + dimension, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles, + + // Provide the current computed size to request scroll gutter calculation (gh-3589) + val + ) + ) + "px"; +} + +jQuery.extend( { + + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "animationIterationCount": true, + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "gridArea": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnStart": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowStart": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: {}, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ), + style = elem.style; + + // Make sure that we're working with the right name. We don't + // want to query the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Gets hook for the prefixed version, then unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // Convert "+=" or "-=" to relative numbers (#7345) + if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { + value = adjustCSS( elem, name, ret ); + + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set (#7116) + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add the unit (except for certain CSS properties) + // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append + // "px" to a few hardcoded values. + if ( type === "number" && !isCustomProp ) { + value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); + } + + // background-* props affect original clone's values + if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !( "set" in hooks ) || + ( value = hooks.set( elem, value, extra ) ) !== undefined ) { + + if ( isCustomProp ) { + style.setProperty( name, value ); + } else { + style[ name ] = value; + } + } + + } else { + + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && + ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { + + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var val, num, hooks, + origName = camelCase( name ), + isCustomProp = rcustomProp.test( name ); + + // Make sure that we're working with the right name. We don't + // want to modify the value if it is a CSS custom property + // since they are user-defined. + if ( !isCustomProp ) { + name = finalPropName( origName ); + } + + // Try prefixed name followed by the unprefixed name + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + // Convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Make numeric if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || isFinite( num ) ? num || 0 : val; + } + + return val; + } +} ); + +jQuery.each( [ "height", "width" ], function( _i, dimension ) { + jQuery.cssHooks[ dimension ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + + // Certain elements can have dimension info if we invisibly show them + // but it must have a current display style that would benefit + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && + + // Support: Safari 8+ + // Table columns in Safari have non-zero offsetWidth & zero + // getBoundingClientRect().width unless display is changed. + // Support: IE <=11 only + // Running getBoundingClientRect on a disconnected node + // in IE throws an error. + ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? + swap( elem, cssShow, function() { + return getWidthOrHeight( elem, dimension, extra ); + } ) : + getWidthOrHeight( elem, dimension, extra ); + } + }, + + set: function( elem, value, extra ) { + var matches, + styles = getStyles( elem ), + + // Only read styles.position if the test has a chance to fail + // to avoid forcing a reflow. + scrollboxSizeBuggy = !support.scrollboxSize() && + styles.position === "absolute", + + // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) + boxSizingNeeded = scrollboxSizeBuggy || extra, + isBorderBox = boxSizingNeeded && + jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + subtract = extra ? + boxModelAdjustment( + elem, + dimension, + extra, + isBorderBox, + styles + ) : + 0; + + // Account for unreliable border-box dimensions by comparing offset* to computed and + // faking a content-box to get border and padding (gh-3699) + if ( isBorderBox && scrollboxSizeBuggy ) { + subtract -= Math.ceil( + elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - + parseFloat( styles[ dimension ] ) - + boxModelAdjustment( elem, dimension, "border", false, styles ) - + 0.5 + ); + } + + // Convert to pixels if value adjustment is needed + if ( subtract && ( matches = rcssNum.exec( value ) ) && + ( matches[ 3 ] || "px" ) !== "px" ) { + + elem.style[ dimension ] = value; + value = jQuery.css( elem, dimension ); + } + + return setPositiveNumber( elem, value, subtract ); + } + }; +} ); + +jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, + function( elem, computed ) { + if ( computed ) { + return ( parseFloat( curCSS( elem, "marginLeft" ) ) || + elem.getBoundingClientRect().left - + swap( elem, { marginLeft: 0 }, function() { + return elem.getBoundingClientRect().left; + } ) + ) + "px"; + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each( { + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // Assumes a single number if not a string + parts = typeof value === "string" ? value.split( " " ) : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( prefix !== "margin" ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +} ); + +jQuery.fn.extend( { + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( Array.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + } +} ); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || jQuery.easing._default; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + // Use a property on the element directly when it is not a DOM element, + // or when there is no matching style property that exists. + if ( tween.elem.nodeType !== 1 || + tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { + return tween.elem[ tween.prop ]; + } + + // Passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails. + // Simple values such as "10px" are parsed to Float; + // complex values such as "rotate(1rad)" are returned as-is. + result = jQuery.css( tween.elem, tween.prop, "" ); + + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + + // Use step hook for back compat. + // Use cssHook if its there. + // Use .style if available and use plain properties where available. + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.nodeType === 1 && ( + jQuery.cssHooks[ tween.prop ] || + tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 only +// Panic based approach to setting things on disconnected nodes +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + }, + _default: "swing" +}; + +jQuery.fx = Tween.prototype.init; + +// Back compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, inProgress, + rfxtypes = /^(?:toggle|show|hide)$/, + rrun = /queueHooks$/; + +function schedule() { + if ( inProgress ) { + if ( document.hidden === false && window.requestAnimationFrame ) { + window.requestAnimationFrame( schedule ); + } else { + window.setTimeout( schedule, jQuery.fx.interval ); + } + + jQuery.fx.tick(); + } +} + +// Animations created synchronously will run synchronously +function createFxNow() { + window.setTimeout( function() { + fxNow = undefined; + } ); + return ( fxNow = Date.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + i = 0, + attrs = { height: type }; + + // If we include width, step value is 1 to do all cssExpand values, + // otherwise step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { + + // We're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, + isBox = "width" in props || "height" in props, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHiddenWithinTree( elem ), + dataShow = dataPriv.get( elem, "fxshow" ); + + // Queue-skipping animations hijack the fx hooks + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always( function() { + + // Ensure the complete handler is called before this completes + anim.always( function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + } ); + } ); + } + + // Detect show/hide animations + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.test( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // Pretend to be hidden if this is a "show" and + // there is still data from a stopped show/hide + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + + // Ignore all other no-op show/hide data + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + } + } + + // Bail out if this is a no-op like .hide().hide() + propTween = !jQuery.isEmptyObject( props ); + if ( !propTween && jQuery.isEmptyObject( orig ) ) { + return; + } + + // Restrict "overflow" and "display" styles during box animations + if ( isBox && elem.nodeType === 1 ) { + + // Support: IE <=9 - 11, Edge 12 - 15 + // Record all 3 overflow attributes because IE does not infer the shorthand + // from identically-valued overflowX and overflowY and Edge just mirrors + // the overflowX value there. + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Identify a display type, preferring old show/hide data over the CSS cascade + restoreDisplay = dataShow && dataShow.display; + if ( restoreDisplay == null ) { + restoreDisplay = dataPriv.get( elem, "display" ); + } + display = jQuery.css( elem, "display" ); + if ( display === "none" ) { + if ( restoreDisplay ) { + display = restoreDisplay; + } else { + + // Get nonempty value(s) by temporarily forcing visibility + showHide( [ elem ], true ); + restoreDisplay = elem.style.display || restoreDisplay; + display = jQuery.css( elem, "display" ); + showHide( [ elem ] ); + } + } + + // Animate inline elements as inline-block + if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { + if ( jQuery.css( elem, "float" ) === "none" ) { + + // Restore the original display value at the end of pure show/hide animations + if ( !propTween ) { + anim.done( function() { + style.display = restoreDisplay; + } ); + if ( restoreDisplay == null ) { + display = style.display; + restoreDisplay = display === "none" ? "" : display; + } + } + style.display = "inline-block"; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + anim.always( function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + } ); + } + + // Implement show/hide animations + propTween = false; + for ( prop in orig ) { + + // General show/hide setup for this element animation + if ( !propTween ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); + } + + // Store hidden/visible for toggle so `.stop().toggle()` "reverses" + if ( toggle ) { + dataShow.hidden = !hidden; + } + + // Show elements before animating them + if ( hidden ) { + showHide( [ elem ], true ); + } + + /* eslint-disable no-loop-func */ + + anim.done( function() { + + /* eslint-enable no-loop-func */ + + // The final step of a "hide" animation is actually hiding the element + if ( !hidden ) { + showHide( [ elem ] ); + } + dataPriv.remove( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + } ); + } + + // Per-property setup + propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = propTween.start; + if ( hidden ) { + propTween.end = propTween.start; + propTween.start = 0; + } + } + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( Array.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // Not quite $.extend, this won't overwrite existing keys. + // Reusing 'index' because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = Animation.prefilters.length, + deferred = jQuery.Deferred().always( function() { + + // Don't match elem in the :animated selector + delete tick.elem; + } ), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + + // Support: Android 2.3 only + // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ] ); + + // If there's more to do, yield + if ( percent < 1 && length ) { + return remaining; + } + + // If this was an empty animation, synthesize a final progress notification + if ( !length ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + } + + // Resolve the animation and report its conclusion + deferred.resolveWith( elem, [ animation ] ); + return false; + }, + animation = deferred.promise( { + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { + specialEasing: {}, + easing: jQuery.easing._default + }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + + // If we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // Resolve when we played the last frame; otherwise, reject + if ( gotoEnd ) { + deferred.notifyWith( elem, [ animation, 1, 0 ] ); + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + } ), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length; index++ ) { + result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + if ( isFunction( result.stop ) ) { + jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = + result.stop.bind( result ); + } + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + // Attach callbacks from options + animation + .progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + } ) + ); + + return animation; +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweeners: { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ); + adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); + return tween; + } ] + }, + + tweener: function( props, callback ) { + if ( isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.match( rnothtmlwhite ); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length; index++ ) { + prop = props[ index ]; + Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; + Animation.tweeners[ prop ].unshift( callback ); + } + }, + + prefilters: [ defaultPrefilter ], + + prefilter: function( callback, prepend ) { + if ( prepend ) { + Animation.prefilters.unshift( callback ); + } else { + Animation.prefilters.push( callback ); + } + } +} ); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !isFunction( easing ) && easing + }; + + // Go to the end state if fx are off + if ( jQuery.fx.off ) { + opt.duration = 0; + + } else { + if ( typeof opt.duration !== "number" ) { + if ( opt.duration in jQuery.fx.speeds ) { + opt.duration = jQuery.fx.speeds[ opt.duration ]; + + } else { + opt.duration = jQuery.fx.speeds._default; + } + } + } + + // Normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend( { + fadeTo: function( speed, to, easing, callback ) { + + // Show any hidden elements after setting opacity to 0 + return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() + + // Animate to the value specified + .end().animate( { opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || dataPriv.get( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue ) { + this.queue( type || "fx", [] ); + } + + return this.each( function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = dataPriv.get( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && + ( type == null || timers[ index ].queue === type ) ) { + + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // Start the next in the queue if the last step wasn't forced. + // Timers currently will call their complete callbacks, which + // will dequeue but only if they were gotoEnd. + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + } ); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each( function() { + var index, + data = dataPriv.get( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // Enable finishing flag on private data + data.finish = true; + + // Empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // Look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // Look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // Turn off finishing flag + delete data.finish; + } ); + } +} ); + +jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +} ); + +// Generate shortcuts for custom animations +jQuery.each( { + slideDown: genFx( "show" ), + slideUp: genFx( "hide" ), + slideToggle: genFx( "toggle" ), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +} ); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + i = 0, + timers = jQuery.timers; + + fxNow = Date.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + + // Run the timer and safely remove it when done (allowing for external removal) + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + jQuery.fx.start(); +}; + +jQuery.fx.interval = 13; +jQuery.fx.start = function() { + if ( inProgress ) { + return; + } + + inProgress = true; + schedule(); +}; + +jQuery.fx.stop = function() { + inProgress = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = window.setTimeout( next, time ); + hooks.stop = function() { + window.clearTimeout( timeout ); + }; + } ); +}; + + +( function() { + var input = document.createElement( "input" ), + select = document.createElement( "select" ), + opt = select.appendChild( document.createElement( "option" ) ); + + input.type = "checkbox"; + + // Support: Android <=4.3 only + // Default value for a checkbox should be "on" + support.checkOn = input.value !== ""; + + // Support: IE <=11 only + // Must access selectedIndex to make default options select + support.optSelected = opt.selected; + + // Support: IE <=11 only + // An input loses its value after becoming a radio + input = document.createElement( "input" ); + input.value = "t"; + input.type = "radio"; + support.radioValue = input.value === "t"; +} )(); + + +var boolHook, + attrHandle = jQuery.expr.attrHandle; + +jQuery.fn.extend( { + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each( function() { + jQuery.removeAttr( this, name ); + } ); + } +} ); + +jQuery.extend( { + attr: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set attributes on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + // Attribute hooks are determined by the lowercase version + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + hooks = jQuery.attrHooks[ name.toLowerCase() ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); + } + + if ( value !== undefined ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + } + + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + elem.setAttribute( name, value + "" ); + return value; + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? undefined : ret; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && + nodeName( elem, "input" ) ) { + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + removeAttr: function( elem, value ) { + var name, + i = 0, + + // Attribute names can contain non-HTML whitespace characters + // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 + attrNames = value && value.match( rnothtmlwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( ( name = attrNames[ i++ ] ) ) { + elem.removeAttribute( name ); + } + } + } +} ); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + elem.setAttribute( name, name ); + } + return name; + } +}; + +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = function( elem, name, isXML ) { + var ret, handle, + lowercaseName = name.toLowerCase(); + + if ( !isXML ) { + + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ lowercaseName ]; + attrHandle[ lowercaseName ] = ret; + ret = getter( elem, name, isXML ) != null ? + lowercaseName : + null; + attrHandle[ lowercaseName ] = handle; + } + return ret; + }; +} ); + + + + +var rfocusable = /^(?:input|select|textarea|button)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend( { + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + return this.each( function() { + delete this[ jQuery.propFix[ name ] || name ]; + } ); + } +} ); + +jQuery.extend( { + prop: function( elem, name, value ) { + var ret, hooks, + nType = elem.nodeType; + + // Don't get/set properties on text, comment and attribute nodes + if ( nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && + ( ret = hooks.set( elem, value, name ) ) !== undefined ) { + return ret; + } + + return ( elem[ name ] = value ); + } + + if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { + return ret; + } + + return elem[ name ]; + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + + // Support: IE <=9 - 11 only + // elem.tabIndex doesn't always return the + // correct value when it hasn't been explicitly set + // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + if ( tabindex ) { + return parseInt( tabindex, 10 ); + } + + if ( + rfocusable.test( elem.nodeName ) || + rclickable.test( elem.nodeName ) && + elem.href + ) { + return 0; + } + + return -1; + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + } +} ); + +// Support: IE <=11 only +// Accessing the selectedIndex property +// forces the browser to respect setting selected +// on the option +// The getter ensures a default option is selected +// when in an optgroup +// eslint rule "no-unused-expressions" is disabled for this code +// since it considers such accessions noop +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent && parent.parentNode ) { + parent.parentNode.selectedIndex; + } + return null; + }, + set: function( elem ) { + + /* eslint no-unused-expressions: "off" */ + + var parent = elem.parentNode; + if ( parent ) { + parent.selectedIndex; + + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }; +} + +jQuery.each( [ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +} ); + + + + + // Strip and collapse whitespace according to HTML spec + // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace + function stripAndCollapse( value ) { + var tokens = value.match( rnothtmlwhite ) || []; + return tokens.join( " " ); + } + + +function getClass( elem ) { + return elem.getAttribute && elem.getAttribute( "class" ) || ""; +} + +function classesToArray( value ) { + if ( Array.isArray( value ) ) { + return value; + } + if ( typeof value === "string" ) { + return value.match( rnothtmlwhite ) || []; + } + return []; +} + +jQuery.fn.extend( { + addClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, curValue, clazz, j, finalValue, + i = 0; + + if ( isFunction( value ) ) { + return this.each( function( j ) { + jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); + } ); + } + + if ( !arguments.length ) { + return this.attr( "class", "" ); + } + + classes = classesToArray( value ); + + if ( classes.length ) { + while ( ( elem = this[ i++ ] ) ) { + curValue = getClass( elem ); + + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); + + if ( cur ) { + j = 0; + while ( ( clazz = classes[ j++ ] ) ) { + + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) > -1 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // Only assign if different to avoid unneeded rendering. + finalValue = stripAndCollapse( cur ); + if ( curValue !== finalValue ) { + elem.setAttribute( "class", finalValue ); + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isValidValue = type === "string" || Array.isArray( value ); + + if ( typeof stateVal === "boolean" && isValidValue ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( isFunction( value ) ) { + return this.each( function( i ) { + jQuery( this ).toggleClass( + value.call( this, i, getClass( this ), stateVal ), + stateVal + ); + } ); + } + + return this.each( function() { + var className, i, self, classNames; + + if ( isValidValue ) { + + // Toggle individual class names + i = 0; + self = jQuery( this ); + classNames = classesToArray( value ); + + while ( ( className = classNames[ i++ ] ) ) { + + // Check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( value === undefined || type === "boolean" ) { + className = getClass( this ); + if ( className ) { + + // Store className if set + dataPriv.set( this, "__className__", className ); + } + + // If the element has a class name or if we're passed `false`, + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + if ( this.setAttribute ) { + this.setAttribute( "class", + className || value === false ? + "" : + dataPriv.get( this, "__className__" ) || "" + ); + } + } + } ); + }, + + hasClass: function( selector ) { + var className, elem, + i = 0; + + className = " " + selector + " "; + while ( ( elem = this[ i++ ] ) ) { + if ( elem.nodeType === 1 && + ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { + return true; + } + } + + return false; + } +} ); + + + + +var rreturn = /\r/g; + +jQuery.fn.extend( { + val: function( value ) { + var hooks, ret, valueIsFunction, + elem = this[ 0 ]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || + jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && + "get" in hooks && + ( ret = hooks.get( elem, "value" ) ) !== undefined + ) { + return ret; + } + + ret = elem.value; + + // Handle most common string cases + if ( typeof ret === "string" ) { + return ret.replace( rreturn, "" ); + } + + // Handle cases where value is null/undef or number + return ret == null ? "" : ret; + } + + return; + } + + valueIsFunction = isFunction( value ); + + return this.each( function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( valueIsFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + + } else if ( typeof val === "number" ) { + val += ""; + + } else if ( Array.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + } ); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + } ); + } +} ); + +jQuery.extend( { + valHooks: { + option: { + get: function( elem ) { + + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + + // Support: IE <=10 - 11 only + // option.text throws exceptions (#14686, #14858) + // Strip and collapse whitespace + // https://html.spec.whatwg.org/#strip-and-collapse-whitespace + stripAndCollapse( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, i, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one", + values = one ? null : [], + max = one ? index + 1 : options.length; + + if ( index < 0 ) { + i = max; + + } else { + i = one ? index : 0; + } + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // Support: IE <=9 only + // IE8-9 doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + + // Don't return options that are disabled or in a disabled optgroup + !option.disabled && + ( !option.parentNode.disabled || + !nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + /* eslint-disable no-cond-assign */ + + if ( option.selected = + jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 + ) { + optionSet = true; + } + + /* eslint-enable no-cond-assign */ + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + } +} ); + +// Radios and checkboxes getter/setter +jQuery.each( [ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( Array.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + return elem.getAttribute( "value" ) === null ? "on" : elem.value; + }; + } +} ); + + + + +// Return jQuery for attributes-only inclusion + + +support.focusin = "onfocusin" in window; + + +var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + stopPropagationCallback = function( e ) { + e.stopPropagation(); + }; + +jQuery.extend( jQuery.event, { + + trigger: function( event, data, elem, onlyHandlers ) { + + var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; + + cur = lastElement = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "." ) > -1 ) { + + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split( "." ); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf( ":" ) < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join( "." ); + event.rnamespace = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === ( elem.ownerDocument || document ) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { + lastElement = cur; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( + dataPriv.get( cur, "events" ) || Object.create( null ) + )[ event.type ] && + dataPriv.get( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( ( !special._default || + special._default.apply( eventPath.pop(), data ) === false ) && + acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name as the event. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + + if ( event.isPropagationStopped() ) { + lastElement.addEventListener( type, stopPropagationCallback ); + } + + elem[ type ](); + + if ( event.isPropagationStopped() ) { + lastElement.removeEventListener( type, stopPropagationCallback ); + } + + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + // Piggyback on a donor event to simulate a different one + // Used only for `focus(in | out)` events + simulate: function( type, elem, event ) { + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true + } + ); + + jQuery.event.trigger( e, null, elem ); + } + +} ); + +jQuery.fn.extend( { + + trigger: function( type, data ) { + return this.each( function() { + jQuery.event.trigger( type, data, this ); + } ); + }, + triggerHandler: function( type, data ) { + var elem = this[ 0 ]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +} ); + + +// Support: Firefox <=44 +// Firefox doesn't have focus(in | out) events +// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 +// +// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 +// focus(in | out) events fire after focus & blur events, +// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order +// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 +if ( !support.focusin ) { + jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + + // Handle: regular nodes (via `this.ownerDocument`), window + // (via `this.document`) & document (via `this`). + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this.document || this, + attaches = dataPriv.access( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + dataPriv.remove( doc, fix ); + + } else { + dataPriv.access( doc, fix, attaches ); + } + } + }; + } ); +} +var location = window.location; + +var nonce = { guid: Date.now() }; + +var rquery = ( /\?/ ); + + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml; + if ( !data || typeof data !== "string" ) { + return null; + } + + // Support: IE 9 - 11 only + // IE throws on parseFromString with invalid input. + try { + xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); + } catch ( e ) { + xml = undefined; + } + + if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( Array.isArray( obj ) ) { + + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + + // Item is non-scalar (array or object), encode its numeric index. + buildParams( + prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", + v, + traditional, + add + ); + } + } ); + + } else if ( !traditional && toType( obj ) === "object" ) { + + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, valueOrFunction ) { + + // If value is a function, invoke it and use its return value + var value = isFunction( valueOrFunction ) ? + valueOrFunction() : + valueOrFunction; + + s[ s.length ] = encodeURIComponent( key ) + "=" + + encodeURIComponent( value == null ? "" : value ); + }; + + if ( a == null ) { + return ""; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + } ); + + } else { + + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ); +}; + +jQuery.fn.extend( { + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map( function() { + + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + } ) + .filter( function() { + var type = this.type; + + // Use .is( ":disabled" ) so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + } ) + .map( function( _i, elem ) { + var val = jQuery( this ).val(); + + if ( val == null ) { + return null; + } + + if ( Array.isArray( val ) ) { + return jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ); + } + + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + } ).get(); + } +} ); + + +var + r20 = /%20/g, + rhash = /#.*$/, + rantiCache = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, + + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat( "*" ), + + // Anchor tag for parsing the document origin + originAnchor = document.createElement( "a" ); + originAnchor.href = location.href; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; + + if ( isFunction( func ) ) { + + // For each dataType in the dataTypeExpression + while ( ( dataType = dataTypes[ i++ ] ) ) { + + // Prepend if requested + if ( dataType[ 0 ] === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); + + // Otherwise append + } else { + ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && + !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + } ); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s.throws ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { + state: "parsererror", + error: conv ? e : "No conversion from " + prev + " to " + current + }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend( { + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: location.href, + type: "GET", + isLocal: rlocalProtocol.test( location.protocol ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /\bxml\b/, + html: /\bhtml/, + json: /\bjson\b/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": JSON.parse, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var transport, + + // URL without anti-cache param + cacheURL, + + // Response headers + responseHeadersString, + responseHeaders, + + // timeout handle + timeoutTimer, + + // Url cleanup var + urlAnchor, + + // Request state (becomes false upon send and true upon completion) + completed, + + // To know if global events are to be dispatched + fireGlobals, + + // Loop variable + i, + + // uncached part of the url + uncached, + + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + + // Callbacks context + callbackContext = s.context || s, + + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && + ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + + // Status-dependent callbacks + statusCode = s.statusCode || {}, + + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + + // Default abort message + strAbort = "canceled", + + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( completed ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[ 1 ].toLowerCase() + " " ] = + ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) + .concat( match[ 2 ] ); + } + } + match = responseHeaders[ key.toLowerCase() + " " ]; + } + return match == null ? null : match.join( ", " ); + }, + + // Raw string + getAllResponseHeaders: function() { + return completed ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( completed == null ) { + name = requestHeadersNames[ name.toLowerCase() ] = + requestHeadersNames[ name.toLowerCase() ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( completed == null ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( completed ) { + + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } else { + + // Lazy-add the new callbacks in a way that preserves old ones + for ( code in map ) { + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ); + + // Add protocol if not provided (prefilters might expect it) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || location.href ) + "" ) + .replace( rprotocol, location.protocol + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; + + // A cross-domain request is in order when the origin doesn't match the current origin. + if ( s.crossDomain == null ) { + urlAnchor = document.createElement( "a" ); + + // Support: IE <=8 - 11, Edge 12 - 15 + // IE throws exception on accessing the href property if url is malformed, + // e.g. http://example.com:80x/ + try { + urlAnchor.href = s.url; + + // Support: IE <=8 - 11 only + // Anchor's host property isn't correctly set when s.url is relative + urlAnchor.href = urlAnchor.href; + s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== + urlAnchor.protocol + "//" + urlAnchor.host; + } catch ( e ) { + + // If there is an error parsing the URL, assume it is crossDomain, + // it can be rejected by the transport if it is invalid + s.crossDomain = true; + } + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( completed ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + // Remove hash to simplify url manipulation + cacheURL = s.url.replace( rhash, "" ); + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // Remember the hash so we can put it back + uncached = s.url.slice( cacheURL.length ); + + // If data is available and should be processed, append data to url + if ( s.data && ( s.processData || typeof s.data === "string" ) ) { + cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; + + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add or update anti-cache param if needed + if ( s.cache === false ) { + cacheURL = cacheURL.replace( rantiCache, "$1" ); + uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + + uncached; + } + + // Put hash and anti-cache on the URL that will be requested (gh-1732) + s.url = cacheURL + uncached; + + // Change '%20' to '+' if this is encoded form body content (gh-2658) + } else if ( s.data && s.processData && + ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { + s.data = s.data.replace( r20, "+" ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? + s.accepts[ s.dataTypes[ 0 ] ] + + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && + ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { + + // Abort if not done already and return + return jqXHR.abort(); + } + + // Aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + completeDeferred.add( s.complete ); + jqXHR.done( s.success ); + jqXHR.fail( s.error ); + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + + // If request was aborted inside ajaxSend, stop there + if ( completed ) { + return jqXHR; + } + + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = window.setTimeout( function() { + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + completed = false; + transport.send( requestHeaders, done ); + } catch ( e ) { + + // Rethrow post-completion exceptions + if ( completed ) { + throw e; + } + + // Propagate others as results + done( -1, e ); + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Ignore repeat invocations + if ( completed ) { + return; + } + + completed = true; + + // Clear timeout if it exists + if ( timeoutTimer ) { + window.clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Use a noop converter for missing script + if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { + s.converters[ "text script" ] = function() {}; + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader( "Last-Modified" ); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader( "etag" ); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + + // Extract error from statusText and normalize for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +} ); + +jQuery.each( [ "get", "post" ], function( _i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + + // Shift arguments if data argument was omitted + if ( isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + // The url can be an options object (which then must have .url) + return jQuery.ajax( jQuery.extend( { + url: url, + type: method, + dataType: type, + data: data, + success: callback + }, jQuery.isPlainObject( url ) && url ) ); + }; +} ); + +jQuery.ajaxPrefilter( function( s ) { + var i; + for ( i in s.headers ) { + if ( i.toLowerCase() === "content-type" ) { + s.contentType = s.headers[ i ] || ""; + } + } +} ); + + +jQuery._evalUrl = function( url, options, doc ) { + return jQuery.ajax( { + url: url, + + // Make this explicit, since user can override this through ajaxSetup (#11264) + type: "GET", + dataType: "script", + cache: true, + async: false, + global: false, + + // Only evaluate the response if it is successful (gh-4126) + // dataFilter is not invoked for failure responses, so using it instead + // of the default converter is kludgy but it works. + converters: { + "text script": function() {} + }, + dataFilter: function( response ) { + jQuery.globalEval( response, options, doc ); + } + } ); +}; + + +jQuery.fn.extend( { + wrapAll: function( html ) { + var wrap; + + if ( this[ 0 ] ) { + if ( isFunction( html ) ) { + html = html.call( this[ 0 ] ); + } + + // The elements to wrap the target around + wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); + + if ( this[ 0 ].parentNode ) { + wrap.insertBefore( this[ 0 ] ); + } + + wrap.map( function() { + var elem = this; + + while ( elem.firstElementChild ) { + elem = elem.firstElementChild; + } + + return elem; + } ).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( isFunction( html ) ) { + return this.each( function( i ) { + jQuery( this ).wrapInner( html.call( this, i ) ); + } ); + } + + return this.each( function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + } ); + }, + + wrap: function( html ) { + var htmlIsFunction = isFunction( html ); + + return this.each( function( i ) { + jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); + } ); + }, + + unwrap: function( selector ) { + this.parent( selector ).not( "body" ).each( function() { + jQuery( this ).replaceWith( this.childNodes ); + } ); + return this; + } +} ); + + +jQuery.expr.pseudos.hidden = function( elem ) { + return !jQuery.expr.pseudos.visible( elem ); +}; +jQuery.expr.pseudos.visible = function( elem ) { + return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); +}; + + + + +jQuery.ajaxSettings.xhr = function() { + try { + return new window.XMLHttpRequest(); + } catch ( e ) {} +}; + +var xhrSuccessStatus = { + + // File protocol always yields status code 0, assume 200 + 0: 200, + + // Support: IE <=9 only + // #1450: sometimes IE returns 1223 when it should be 204 + 1223: 204 + }, + xhrSupported = jQuery.ajaxSettings.xhr(); + +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +support.ajax = xhrSupported = !!xhrSupported; + +jQuery.ajaxTransport( function( options ) { + var callback, errorCallback; + + // Cross domain only allowed if supported through XMLHttpRequest + if ( support.cors || xhrSupported && !options.crossDomain ) { + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(); + + xhr.open( + options.type, + options.url, + options.async, + options.username, + options.password + ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + + // Callback + callback = function( type ) { + return function() { + if ( callback ) { + callback = errorCallback = xhr.onload = + xhr.onerror = xhr.onabort = xhr.ontimeout = + xhr.onreadystatechange = null; + + if ( type === "abort" ) { + xhr.abort(); + } else if ( type === "error" ) { + + // Support: IE <=9 only + // On a manual native abort, IE9 throws + // errors on any property access that is not readyState + if ( typeof xhr.status !== "number" ) { + complete( 0, "error" ); + } else { + complete( + + // File: protocol always yields status 0; see #8605, #14207 + xhr.status, + xhr.statusText + ); + } + } else { + complete( + xhrSuccessStatus[ xhr.status ] || xhr.status, + xhr.statusText, + + // Support: IE <=9 only + // IE9 has no XHR2 but throws on binary (trac-11426) + // For XHR2 non-text, let the caller handle it (gh-2498) + ( xhr.responseType || "text" ) !== "text" || + typeof xhr.responseText !== "string" ? + { binary: xhr.response } : + { text: xhr.responseText }, + xhr.getAllResponseHeaders() + ); + } + } + }; + }; + + // Listen to events + xhr.onload = callback(); + errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); + + // Support: IE 9 only + // Use onreadystatechange to replace onabort + // to handle uncaught aborts + if ( xhr.onabort !== undefined ) { + xhr.onabort = errorCallback; + } else { + xhr.onreadystatechange = function() { + + // Check readyState before timeout as it changes + if ( xhr.readyState === 4 ) { + + // Allow onerror to be called first, + // but that will not handle a native abort + // Also, save errorCallback to a variable + // as xhr.onerror cannot be accessed + window.setTimeout( function() { + if ( callback ) { + errorCallback(); + } + } ); + } + }; + } + + // Create the abort callback + callback = callback( "abort" ); + + try { + + // Do send the request (this may raise an exception) + xhr.send( options.hasContent && options.data || null ); + } catch ( e ) { + + // #14683: Only rethrow if this hasn't been notified as an error yet + if ( callback ) { + throw e; + } + } + }, + + abort: function() { + if ( callback ) { + callback(); + } + } + }; + } +} ); + + + + +// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) +jQuery.ajaxPrefilter( function( s ) { + if ( s.crossDomain ) { + s.contents.script = false; + } +} ); + +// Install script dataType +jQuery.ajaxSetup( { + accepts: { + script: "text/javascript, application/javascript, " + + "application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /\b(?:java|ecma)script\b/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +} ); + +// Handle cache's special case and crossDomain +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + } +} ); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function( s ) { + + // This transport only deals with cross domain or forced-by-attrs requests + if ( s.crossDomain || s.scriptAttrs ) { + var script, callback; + return { + send: function( _, complete ) { + script = jQuery( " - - - - + + + + @@ -60,7 +60,7 @@
- 33.2 + 33.10
@@ -108,6 +108,7 @@
  • Profiles
  • Build an image and upload results
  • Upload an existing image
  • +
  • Debugging
  • mkksiso
  • @@ -184,17 +185,19 @@

    Brian C. Lane <bcl@redhat.com>

    -

    composer-cli is used to interact with the lorax-composer API server, managing blueprints, exploring available packages, and building new images.

    -

    It requires lorax-composer to be installed on the -local system, and the user running it needs to be a member of the weldr -group. They do not need to be root, but all of the security precautions apply.

    +

    composer-cli is an interactive tool for use with a WELDR API server, +managing blueprints, exploring available packages, and building new images. +lorax-composer <lorax-composer.html> and osbuild-composer +<https://osbuild.org> both implement compatible servers.

    +

    It requires the server to be installed on the local system, and the user +running it needs to be a member of the weldr group. They do not need to be +root, but all of the security precautions +apply.

    composer-cli cmdline arguments¶

    Lorax Composer commandline tool

    -

    Providers¶

    @@ -467,6 +477,19 @@ can monitor with co

    This will output the UUID of the upload, which can then be used to monitor the status in the same way described above.

    +
    +

    Debugging¶

    +

    There are a couple of arguments that can be helpful when debugging problems. +These are only meant for debugging and should not be used to script access to +the API. If you need to do that you can communicate with it directly in the +language of your choice.

    +

    --json will return the server's response as a nicely formatted json output +instead of printing what the command would usually print.

    +

    --test=1 will cause a compose start to start creating an image, and then +end with a failed state.

    +

    --test=2 will cause a compose to start and then end with a finished state, +without actually composing anything.

    +
    diff --git a/docs/html/composer.cli.html b/docs/html/composer.cli.html index 61703335..213228ee 100644 --- a/docs/html/composer.cli.html +++ b/docs/html/composer.cli.html @@ -8,7 +8,7 @@ - composer.cli package — Lorax 33.2 documentation + composer.cli package — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    @@ -184,9 +184,9 @@

    composer.cli.blueprints module¶

    -
    +
    -composer.cli.blueprints.blueprints_changes(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_changes(socket_path, api_version, args, show_json=False)[source]¶

    Display the changes for each of the blueprints

    Parameters
    @@ -201,9 +201,9 @@

    blueprints changes <blueprint,...> Display the changes for each blueprint.

    -
    +
    -composer.cli.blueprints.blueprints_cmd(opts)[source]¶
    +composer.cli.blueprints.blueprints_cmd(opts)[source]¶

    Process blueprints commands

    Parameters
    @@ -219,9 +219,9 @@

    This dispatches the blueprints commands to a function

    -
    +
    -composer.cli.blueprints.blueprints_delete(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_delete(socket_path, api_version, args, show_json=False)[source]¶

    Delete a blueprint from the server

    Parameters
    @@ -236,9 +236,9 @@

    delete <blueprint> Delete a blueprint from the server

    -
    +
    -composer.cli.blueprints.blueprints_depsolve(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_depsolve(socket_path, api_version, args, show_json=False)[source]¶

    Display the packages needed to install the blueprint

    Parameters
    @@ -253,9 +253,9 @@

    blueprints depsolve <blueprint,...> Display the packages needed to install the blueprint.

    -
    +
    -composer.cli.blueprints.blueprints_diff(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_diff(socket_path, api_version, args, show_json=False)[source]¶

    Display the differences between 2 versions of a blueprint

    Parameters
    @@ -274,9 +274,9 @@
    -
    +
    -composer.cli.blueprints.blueprints_freeze(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_freeze(socket_path, api_version, args, show_json=False)[source]¶

    Handle the blueprints freeze commands

    Parameters
    @@ -293,9 +293,9 @@ blueprints freeze show <blueprint,...> Display the frozen blueprint in TOM blueprints freeze save <blueprint,...> Save the frozen blueprint to a file, <blueprint-name>.frozen.toml.

    -
    +
    -composer.cli.blueprints.blueprints_freeze_save(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_freeze_save(socket_path, api_version, args, show_json=False)[source]¶

    Save the frozen blueprint to a TOML file

    Parameters
    @@ -310,9 +310,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints freeze save <blueprint,...> Save the frozen blueprint to a file, <blueprint-name>.frozen.toml.

    -
    +
    -composer.cli.blueprints.blueprints_freeze_show(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_freeze_show(socket_path, api_version, args, show_json=False)[source]¶

    Show the frozen blueprint in TOML format

    Parameters
    @@ -327,9 +327,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints freeze show <blueprint,...> Display the frozen blueprint in TOML format.

    -
    +
    -composer.cli.blueprints.blueprints_list(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_list(socket_path, api_version, args, show_json=False)[source]¶

    Output the list of available blueprints

    Parameters
    @@ -344,9 +344,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints list

    -
    +
    -composer.cli.blueprints.blueprints_push(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_push(socket_path, api_version, args, show_json=False)[source]¶

    Push a blueprint TOML file to the server, updating the blueprint

    Parameters
    @@ -361,9 +361,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    push <blueprint> Push a blueprint TOML file to the server.

    -
    +
    -composer.cli.blueprints.blueprints_save(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_save(socket_path, api_version, args, show_json=False)[source]¶

    Save the blueprint to a TOML file

    Parameters
    @@ -378,9 +378,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints save <blueprint,...> Save the blueprint to a file, <blueprint-name>.toml

    -
    +
    -composer.cli.blueprints.blueprints_show(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_show(socket_path, api_version, args, show_json=False)[source]¶

    Show the blueprints, in TOML format

    Parameters
    @@ -396,9 +396,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    Multiple blueprints will be separated by

    -
    +
    -composer.cli.blueprints.blueprints_tag(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_tag(socket_path, api_version, args, show_json=False)[source]¶

    Tag the most recent blueprint commit as a release

    Parameters
    @@ -413,9 +413,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints tag <blueprint> Tag the most recent blueprint commit as a release.

    -
    +
    -composer.cli.blueprints.blueprints_undo(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_undo(socket_path, api_version, args, show_json=False)[source]¶

    Undo changes to a blueprint

    Parameters
    @@ -430,9 +430,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints undo <blueprint> <commit> Undo changes to a blueprint by reverting to the selected commit.

    -
    +
    -composer.cli.blueprints.blueprints_workspace(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.blueprints.blueprints_workspace(socket_path, api_version, args, show_json=False)[source]¶

    Push the blueprint TOML to the temporary workspace storage

    Parameters
    @@ -447,9 +447,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    blueprints workspace <blueprint> Push the blueprint TOML to the temporary workspace storage.

    -
    +
    -composer.cli.blueprints.dict_names(lst)[source]¶
    +composer.cli.blueprints.dict_names(lst)[source]¶

    Return comma-separated list of the dict's name/user fields

    Parameters
    @@ -465,9 +465,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    root, norm

    -
    +
    -composer.cli.blueprints.prettyCommitDetails(change, indent=4)[source]¶
    +composer.cli.blueprints.prettyCommitDetails(change, indent=4)[source]¶

    Print the blueprint's change in a nice way

    Parameters
    @@ -479,9 +479,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file
    -
    +
    -composer.cli.blueprints.pretty_dict(d)[source]¶
    +composer.cli.blueprints.pretty_dict(d)[source]¶

    Return the dict as a human readable single line

    Parameters
    @@ -497,9 +497,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    key="str", key="str1,str2", ...

    -
    +
    -composer.cli.blueprints.pretty_diff_entry(diff)[source]¶
    +composer.cli.blueprints.pretty_diff_entry(diff)[source]¶

    Generate nice diff entry string.

    Parameters
    @@ -514,7 +514,7 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    composer.cli.cmdline module¶

    -
    +
    composer.cli.cmdline.composer_cli_parser()[source]¶

    Return the ArgumentParser for composer-cli

    @@ -523,9 +523,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    composer.cli.compose module¶

    -
    +
    -composer.cli.compose.compose_cancel(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_cancel(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Cancel a running compose

    Parameters
    @@ -542,9 +542,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    This will cancel a running compose. It does nothing if the compose has finished.

    -
    +
    -composer.cli.compose.compose_cmd(opts)[source]¶
    +composer.cli.compose.compose_cmd(opts)[source]¶

    Process compose commands

    Parameters
    @@ -558,11 +558,15 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file

    This dispatches the compose commands to a function

    +

    compose_cmd expects api to be passed. eg.

    +
    +

    {"version": 1, "backend": "lorax-composer"}

    +
    -
    +
    -composer.cli.compose.compose_delete(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_delete(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Delete a finished compose's results

    Parameters
    @@ -580,9 +584,9 @@ blueprints freeze save <blueprint,...> Save the frozen blueprint to a file or failed, not a running compose.

    -
    +
    -composer.cli.compose.compose_image(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_image(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Download the compose's output image

    Parameters
    @@ -600,9 +604,9 @@ or failed, not a running compose.

    of compose that was selected.

    -
    +
    -composer.cli.compose.compose_info(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_info(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Return detailed information about the compose

    Parameters
    @@ -619,15 +623,15 @@ of compose that was selected.

    This returns information about the compose, including the blueprint and the dependencies.

    -
    +
    -composer.cli.compose.compose_list(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_list(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Return a simple list of compose identifiers

    -
    +
    -composer.cli.compose.compose_log(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_log(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Show the last part of the compose log

    Parameters
    @@ -645,9 +649,9 @@ of compose that was selected.

    during the build.

    -
    +
    -composer.cli.compose.compose_logs(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_logs(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Download a tar of the compose's logs

    Parameters
    @@ -664,9 +668,9 @@ during the build.

    Saves the logs as uuid-logs.tar

    -
    +
    -composer.cli.compose.compose_metadata(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_metadata(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Download a tar file of the compose's metadata

    Parameters
    @@ -683,9 +687,28 @@ during the build.

    Saves the metadata as uuid-metadata.tar

    -
    +
    +
    +composer.cli.compose.compose_ostree(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶
    +

    Start a new ostree compose using the selected blueprint and type

    +
    +
    Parameters
    +
      +
    • socket_path (str) -- Path to the Unix socket to use for API communication

    • +
    • api_version (str) -- Version of the API to talk to. eg. "0"

    • +
    • args (list of str) -- List of remaining arguments from the cmdline

    • +
    • show_json (bool) -- Set to True to show the JSON output instead of the human readable output

    • +
    • testmode (int) -- Set to 1 to simulate a failed compose, set to 2 to simulate a finished one.

    • +
    • api (dict) -- Details about the API server, "version" and "backend"

    • +
    +
    +
    +

    compose start-ostree [--size XXXX] [--parent PARENT] [--ref REF] <BLUEPRINT> <TYPE> [<IMAGE-NAME> <PROFILE.TOML>]

    +
    + +
    -composer.cli.compose.compose_results(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_results(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Download a tar file of the compose's results

    Parameters
    @@ -703,9 +726,9 @@ during the build.

    It is saved as uuid.tar

    -
    +
    -composer.cli.compose.compose_start(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_start(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Start a new compose using the selected blueprint and type

    Parameters
    @@ -715,15 +738,16 @@ It is saved as uuid.tar

  • args (list of str) -- List of remaining arguments from the cmdline

  • show_json (bool) -- Set to True to show the JSON output instead of the human readable output

  • testmode (int) -- Set to 1 to simulate a failed compose, set to 2 to simulate a finished one.

  • +
  • api (dict) -- Details about the API server, "version" and "backend"

  • -

    compose start <blueprint-name> <compose-type> [<image-name> <provider> <profile> | <image-name> <profile.toml>]

    +

    compose start [--size XXX] <blueprint-name> <compose-type> [<image-name> <provider> <profile> | <image-name> <profile.toml>]

    -
    +
    -composer.cli.compose.compose_status(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_status(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Return the status of all known composes

    Parameters
    @@ -740,9 +764,9 @@ It is saved as uuid.tar

    and failed so raw JSON output is not available.

    -
    +
    -composer.cli.compose.compose_types(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.compose.compose_types(socket_path, api_version, args, show_json=False, testmode=0, api=None)[source]¶

    Return information about the supported compose types

    Parameters
    @@ -759,15 +783,73 @@ and failed so raw JSON output is not available.

    include this extra information.

    +
    +
    +composer.cli.compose.get_parent(args)[source]¶
    +

    Return optional --parent argument, and remaining args

    +
    +
    Parameters
    +

    args (list of strings) -- list of arguments

    +
    +
    Returns
    +

    (args, parent)

    +
    +
    Return type
    +

    tuple

    +
    +
    +
    + +
    +
    +composer.cli.compose.get_ref(args)[source]¶
    +

    Return optional --ref argument, and remaining args

    +
    +
    Parameters
    +

    args (list of strings) -- list of arguments

    +
    +
    Returns
    +

    (args, parent)

    +
    +
    Return type
    +

    tuple

    +
    +
    +
    + +
    +
    +composer.cli.compose.get_size(args)[source]¶
    +

    Return optional --size argument, and remaining args

    +
    +
    Parameters
    +

    args (list of strings) -- list of arguments

    +
    +
    Returns
    +

    (args, size)

    +
    +
    Return type
    +

    tuple

    +
    +
    +
      +
    • check size argument for int

    • +
    • check other args for --size in wrong place

    • +
    • raise error? Or just return 0?

    • +
    • no size returns 0 in size

    • +
    • multiply by 1024**2 to make it easier on users to specify large sizes

    • +
    +
    +

    composer.cli.help module¶

    composer.cli.modules module¶

    -
    +
    -composer.cli.modules.modules_cmd(opts)[source]¶
    +composer.cli.modules.modules_cmd(opts)[source]¶

    Process modules commands

    Parameters
    @@ -785,9 +867,9 @@ include this extra information.

    composer.cli.projects module¶

    -
    +
    -composer.cli.projects.projects_cmd(opts)[source]¶
    +composer.cli.projects.projects_cmd(opts)[source]¶

    Process projects commands

    Parameters
    @@ -802,9 +884,9 @@ include this extra information.

    -
    +
    -composer.cli.projects.projects_info(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.projects.projects_info(socket_path, api_version, args, show_json=False)[source]¶

    Output info on a list of projects

    Parameters
    @@ -819,9 +901,9 @@ include this extra information.

    projects info <project,...>

    -
    +
    -composer.cli.projects.projects_list(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.projects.projects_list(socket_path, api_version, args, show_json=False)[source]¶

    Output the list of available projects

    Parameters
    @@ -839,9 +921,9 @@ include this extra information.

    composer.cli.providers module¶

    -
    +
    -composer.cli.providers.providers_cmd(opts)[source]¶
    +composer.cli.providers.providers_cmd(opts)[source]¶

    Process providers commands

    Parameters
    @@ -857,9 +939,9 @@ include this extra information.

    This dispatches the providers commands to a function

    -
    +
    -composer.cli.providers.providers_delete(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_delete(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Delete a profile from a provider

    Parameters
    @@ -875,9 +957,9 @@ include this extra information.

    providers delete <provider> <profile>

    -
    +
    -composer.cli.providers.providers_info(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_info(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Show information about each provider

    Parameters
    @@ -893,9 +975,9 @@ include this extra information.

    providers info <PROVIDER>

    -
    +
    -composer.cli.providers.providers_list(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_list(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return the list of providers

    Parameters
    @@ -911,9 +993,9 @@ include this extra information.

    providers list

    -
    +
    -composer.cli.providers.providers_push(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_push(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Add a new provider profile or overwrite an existing one

    Parameters
    @@ -929,9 +1011,9 @@ include this extra information.

    providers push <profile.toml>

    -
    +
    -composer.cli.providers.providers_save(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_save(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Save a provider's profile to a TOML file

    Parameters
    @@ -947,9 +1029,9 @@ include this extra information.

    providers save <provider> <profile>

    -
    +
    -composer.cli.providers.providers_show(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_show(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return details about a provider

    Parameters
    @@ -965,9 +1047,9 @@ include this extra information.

    providers show <provider> <profile>

    -
    +
    -composer.cli.providers.providers_template(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.providers.providers_template(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return a TOML template for setting the provider's fields

    Parameters
    @@ -986,9 +1068,9 @@ include this extra information.

    composer.cli.sources module¶

    -
    +
    -composer.cli.sources.sources_add(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.sources.sources_add(socket_path, api_version, args, show_json=False)[source]¶

    Add or change a source

    Parameters
    @@ -1003,9 +1085,9 @@ include this extra information.

    sources add <source.toml>

    -
    +
    -composer.cli.sources.sources_cmd(opts)[source]¶
    +composer.cli.sources.sources_cmd(opts)[source]¶

    Process sources commands

    Parameters
    @@ -1020,9 +1102,9 @@ include this extra information.

    -
    +
    -composer.cli.sources.sources_delete(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.sources.sources_delete(socket_path, api_version, args, show_json=False)[source]¶

    Delete a source

    Parameters
    @@ -1037,9 +1119,9 @@ include this extra information.

    sources delete <source-name>

    -
    +
    -composer.cli.sources.sources_info(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.sources.sources_info(socket_path, api_version, args, show_json=False)[source]¶

    Output info on a list of projects

    Parameters
    @@ -1054,9 +1136,9 @@ include this extra information.

    sources info <source-name>

    -
    +
    -composer.cli.sources.sources_list(socket_path, api_version, args, show_json=False)[source]¶
    +composer.cli.sources.sources_list(socket_path, api_version, args, show_json=False)[source]¶

    Output the list of available sources

    Parameters
    @@ -1074,9 +1156,9 @@ include this extra information.

    composer.cli.status module¶

    -
    +
    -composer.cli.status.status_cmd(opts)[source]¶
    +composer.cli.status.status_cmd(opts)[source]¶

    Process status commands

    Parameters
    @@ -1094,9 +1176,9 @@ include this extra information.

    composer.cli.upload module¶

    -
    +
    -composer.cli.upload.upload_cancel(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_cancel(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Cancel the queued or running upload

    Parameters
    @@ -1112,9 +1194,9 @@ include this extra information.

    upload cancel <build-uuid>

    -
    +
    -composer.cli.upload.upload_cmd(opts)[source]¶
    +composer.cli.upload.upload_cmd(opts)[source]¶

    Process upload commands

    Parameters
    @@ -1130,9 +1212,9 @@ include this extra information.

    This dispatches the upload commands to a function

    -
    +
    -composer.cli.upload.upload_delete(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_delete(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Delete an upload and remove it from the build

    Parameters
    @@ -1148,9 +1230,9 @@ include this extra information.

    upload delete <build-uuid>

    -
    +
    -composer.cli.upload.upload_info(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_info(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return detailed information about the upload

    Parameters
    @@ -1167,9 +1249,9 @@ include this extra information.

    This returns information about the upload, including uuid, name, status, service, and image.

    -
    +
    -composer.cli.upload.upload_list(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_list(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return the composes and their associated upload uuids and status

    Parameters
    @@ -1185,9 +1267,9 @@ include this extra information.

    upload list

    -
    +
    -composer.cli.upload.upload_log(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_log(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Return the upload log

    Parameters
    @@ -1203,9 +1285,9 @@ include this extra information.

    upload log <build-uuid>

    -
    +
    -composer.cli.upload.upload_reset(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_reset(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Reset the upload and execute it again

    Parameters
    @@ -1221,9 +1303,9 @@ include this extra information.

    upload reset <build-uuid>

    -
    +
    -composer.cli.upload.upload_start(socket_path, api_version, args, show_json=False, testmode=0)[source]¶
    +composer.cli.upload.upload_start(socket_path, api_version, args, show_json=False, testmode=0)[source]¶

    Start upload up a build uuid image

    Parameters
    @@ -1242,9 +1324,9 @@ include this extra information.

    composer.cli.utilities module¶

    -
    +
    -composer.cli.utilities.argify(args)[source]¶
    +composer.cli.utilities.argify(args)[source]¶

    Take a list of human args and return a list with each item

    Parameters
    @@ -1261,9 +1343,9 @@ include this extra information.

    ["one,two", "three", ",four", ",five,"] returns ["one", "two", "three", "four", "five"]

    -
    +
    -composer.cli.utilities.frozen_toml_filename(blueprint_name)[source]¶
    +composer.cli.utilities.frozen_toml_filename(blueprint_name)[source]¶

    Convert a blueprint name into a filename.toml

    Parameters
    @@ -1278,9 +1360,28 @@ include this extra information.

    -
    +
    +
    +composer.cli.utilities.get_arg(args, name, argtype=None)[source]¶
    +

    Return optional value from args, and remaining args

    +
    +
    Parameters
    +
      +
    • args (list of strings) -- list of arguments

    • +
    • name (string) -- The argument to remove from the args list

    • +
    • argtype (type) -- Type to use for checking the argument value

    • +
    +
    +
    +

    :returns (args, value) +:rtype: tuple

    +

    This removes the optional argument and value from the argument list, returns the new list, +and the value of the argument.

    +
    + +
    -composer.cli.utilities.handle_api_result(result, show_json=False)[source]¶
    +composer.cli.utilities.handle_api_result(result, show_json=False)[source]¶

    Log any errors, return the correct value

    Parameters
    @@ -1297,9 +1398,9 @@ include this extra information.

    not to continue processing the results.

    -
    +
    -composer.cli.utilities.packageNEVRA(pkg)[source]¶
    +composer.cli.utilities.packageNEVRA(pkg)[source]¶

    Return the package info as a NEVRA

    Parameters
    @@ -1314,9 +1415,9 @@ not to continue processing the results.

    -
    +
    -composer.cli.utilities.toml_filename(blueprint_name)[source]¶
    +composer.cli.utilities.toml_filename(blueprint_name)[source]¶

    Convert a blueprint name into a filename.toml

    Parameters
    @@ -1334,9 +1435,9 @@ not to continue processing the results.

    Module contents¶

    -
    +
    -composer.cli.main(opts)[source]¶
    +composer.cli.main(opts)[source]¶

    Main program execution

    Parameters
    diff --git a/docs/html/composer.html b/docs/html/composer.html index 6e003edf..4cb85fe3 100644 --- a/docs/html/composer.html +++ b/docs/html/composer.html @@ -8,7 +8,7 @@ - composer package — Lorax 33.2 documentation + composer package — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    @@ -205,9 +205,9 @@

    composer.http_client module¶

    -
    +
    -composer.http_client.api_url(api_version, url)[source]¶
    +composer.http_client.api_url(api_version, url)[source]¶

    Return the versioned path to the API route

    Parameters
    @@ -225,9 +225,9 @@
    -
    +
    -composer.http_client.append_query(url, query)[source]¶
    +composer.http_client.append_query(url, query)[source]¶

    Add a query argument to a URL

    The query should be of the form "param1=what&param2=ever", i.e., no leading '?'. The new query data will be appended to any existing @@ -248,9 +248,9 @@ query string.

    -
    +
    -composer.http_client.delete_url_json(socket_path, url, timeout=120)[source]¶
    +composer.http_client.delete_url_json(socket_path, url)[source]¶

    Send a DELETE request to the url and return JSON response

    Parameters
    @@ -268,9 +268,9 @@ query string.

    -
    +
    -composer.http_client.download_file(socket_path, url, progress=True)[source]¶
    +composer.http_client.download_file(socket_path, url, progress=True)[source]¶

    Download a file, saving it to the CWD with the included filename

    Parameters
    @@ -282,9 +282,9 @@ query string.

    -
    +
    -composer.http_client.get_filename(headers)[source]¶
    +composer.http_client.get_filename(headers)[source]¶

    Get the filename from the response header

    Parameters
    @@ -302,9 +302,9 @@ query string.

    -
    +
    -composer.http_client.get_url_json(socket_path, url)[source]¶
    +composer.http_client.get_url_json(socket_path, url)[source]¶

    Return the JSON results of a GET request

    Parameters
    @@ -322,9 +322,9 @@ query string.

    -
    +
    -composer.http_client.get_url_json_unlimited(socket_path, url, total_fn=None)[source]¶
    +composer.http_client.get_url_json_unlimited(socket_path, url, total_fn=None)[source]¶

    Return the JSON results of a GET request

    For URLs that use offset/limit arguments, this command will fetch all results for the given request.

    @@ -344,9 +344,9 @@ fetch all results for the given request.

    -
    +
    -composer.http_client.get_url_raw(socket_path, url)[source]¶
    +composer.http_client.get_url_raw(socket_path, url)[source]¶

    Return the raw results of a GET request

    Parameters
    @@ -364,9 +364,9 @@ fetch all results for the given request.

    -
    +
    -composer.http_client.post_url(socket_path, url, body)[source]¶
    +composer.http_client.post_url(socket_path, url, body)[source]¶

    POST raw data to the URL

    Parameters
    @@ -385,9 +385,9 @@ fetch all results for the given request.

    -
    +
    -composer.http_client.post_url_json(socket_path, url, body)[source]¶
    +composer.http_client.post_url_json(socket_path, url, body)[source]¶

    POST some JSON data to the URL

    Parameters
    @@ -406,9 +406,9 @@ fetch all results for the given request.

    -
    +
    -composer.http_client.post_url_toml(socket_path, url, body)[source]¶
    +composer.http_client.post_url_toml(socket_path, url, body)[source]¶

    POST a TOML string to the URL

    Parameters
    @@ -430,11 +430,11 @@ fetch all results for the given request.

    composer.unix_socket module¶

    -
    +
    -class composer.unix_socket.UnixHTTPConnection(socket_path, timeout=60)[source]¶
    +class composer.unix_socket.UnixHTTPConnection(socket_path, timeout=300)[source]¶

    Bases: http.client.HTTPConnection, object

    -
    +
    connect()[source]¶

    Connect to the host and port specified in __init__.

    @@ -442,9 +442,9 @@ fetch all results for the given request.

    -
    +
    -class composer.unix_socket.UnixHTTPConnectionPool(socket_path, timeout=60)[source]¶
    +class composer.unix_socket.UnixHTTPConnectionPool(socket_path, timeout=300)[source]¶

    Bases: urllib3.connectionpool.HTTPConnectionPool

    diff --git a/docs/html/genindex.html b/docs/html/genindex.html index a8fbdc38..182883b4 100644 --- a/docs/html/genindex.html +++ b/docs/html/genindex.html @@ -1,6 +1,5 @@ - @@ -9,7 +8,7 @@ - Index — Lorax 33.2 documentation + Index — Lorax 33.10 documentation @@ -22,10 +21,10 @@ - - - - + + + + @@ -59,7 +58,7 @@
    - 33.2 + 33.10
    @@ -346,6 +345,8 @@
  • compose_logs() (in module composer.cli.compose)
  • compose_metadata() (in module composer.cli.compose) +
  • +
  • compose_ostree() (in module composer.cli.compose)
  • compose_results() (in module composer.cli.compose)
  • @@ -357,40 +358,115 @@ +
  • + composer + +
  • +
  • + composer.cli + +
  • +
  • + composer.cli.blueprints + +
  • - + + - - + - + @@ -1179,7 +1611,7 @@
  • (pylorax.ltmpl.LoraxTemplateRunner method)
  • -
  • repo() (pylorax.api.server.GitLock property) +
  • repo (pylorax.api.server.GitLock attribute)
  • repo_file_exists() (in module pylorax.api.recipes)
  • @@ -1526,6 +1958,10 @@
  • workspace_delete() (in module pylorax.api.workspace)
  • workspace_dir() (in module pylorax.api.workspace) +
  • +
  • workspace_exists() (in module pylorax.api.workspace) +
  • +
  • workspace_filename() (in module pylorax.api.workspace)
  • workspace_read() (in module pylorax.api.workspace)
  • diff --git a/docs/html/index.html b/docs/html/index.html index 38618ac0..e4ba4410 100644 --- a/docs/html/index.html +++ b/docs/html/index.html @@ -8,7 +8,7 @@ - Welcome to Lorax's documentation! — Lorax 33.2 documentation + Welcome to Lorax's documentation! — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -59,7 +59,7 @@
    - 33.2 + 33.10
    @@ -177,6 +177,7 @@

    Documentation for other Lorax Branches¶

      +
    • Fedora 32

    • Fedora 31

    • Fedora 30

    • Fedora 29

    • diff --git a/docs/html/intro.html b/docs/html/intro.html index 4b65fcac..5eb03f37 100644 --- a/docs/html/intro.html +++ b/docs/html/intro.html @@ -8,7 +8,7 @@ - Introduction to Lorax — Lorax 33.2 documentation + Introduction to Lorax — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
      - 33.2 + 33.10
      diff --git a/docs/html/lifted.html b/docs/html/lifted.html index 15dba8ec..ae48a08c 100644 --- a/docs/html/lifted.html +++ b/docs/html/lifted.html @@ -8,7 +8,7 @@ - lifted package — Lorax 33.2 documentation + lifted package — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
      - 33.2 + 33.10
      @@ -180,9 +180,9 @@

    lifted.config module¶

    -
    +
    -lifted.config.configure(conf)[source]¶
    +lifted.config.configure(conf)[source]¶

    Add lifted settings to the configuration

    Parameters
    @@ -199,9 +199,9 @@ directories for the settings.

    lifted.providers module¶

    -
    +
    -lifted.providers.delete_profile(ucfg, provider_name, profile)[source]¶
    +lifted.providers.delete_profile(ucfg, provider_name, profile)[source]¶

    Delete a provider's profile settings file

    Parameters
    @@ -220,9 +220,9 @@ directories for the settings.

    -
    +
    -lifted.providers.list_providers(ucfg)[source]¶
    +lifted.providers.list_providers(ucfg)[source]¶

    List the names of the available upload providers

    Parameters
    @@ -237,9 +237,9 @@ directories for the settings.

    -
    +
    -lifted.providers.load_profiles(ucfg, provider_name)[source]¶
    +lifted.providers.load_profiles(ucfg, provider_name)[source]¶

    Return all settings profiles associated with a provider

    Parameters
    @@ -257,9 +257,9 @@ directories for the settings.

    -
    +
    -lifted.providers.load_settings(ucfg, provider_name, profile)[source]¶
    +lifted.providers.load_settings(ucfg, provider_name, profile)[source]¶

    Load settings for a provider's profile

    Parameters
    @@ -289,9 +289,9 @@ directories for the settings.

    raising an error if the saved settings are invalid.

    -
    +
    -lifted.providers.resolve_playbook_path(ucfg, provider_name)[source]¶
    +lifted.providers.resolve_playbook_path(ucfg, provider_name)[source]¶

    Given a provider's name, return the path to its playbook

    Parameters
    @@ -312,9 +312,9 @@ raising an error if the saved settings are invalid.

    -
    +
    -lifted.providers.resolve_provider(ucfg, provider_name)[source]¶
    +lifted.providers.resolve_provider(ucfg, provider_name)[source]¶

    Get information about the specified provider as defined in that provider's provider.toml, including the provider's display name and expected settings.

    @@ -342,9 +342,9 @@ follows an expected pattern.

    -
    +
    -lifted.providers.save_settings(ucfg, provider_name, profile, settings)[source]¶
    +lifted.providers.save_settings(ucfg, provider_name, profile, settings)[source]¶

    Save (and overwrite) settings for a given provider

    Parameters
    @@ -361,9 +361,9 @@ follows an expected pattern.

    -
    +
    -lifted.providers.validate_settings(ucfg, provider_name, settings, image_name=None)[source]¶
    +lifted.providers.validate_settings(ucfg, provider_name, settings, image_name=None)[source]¶

    Raise a ValueError if any settings are invalid

    Parameters
    @@ -386,9 +386,9 @@ follows an expected pattern.

    lifted.queue module¶

    -
    +
    -lifted.queue.cancel_upload(ucfg, uuid)[source]¶
    +lifted.queue.cancel_upload(ucfg, uuid)[source]¶

    Cancel an upload

    Parameters
    @@ -400,9 +400,9 @@ follows an expected pattern.

    -
    +
    -lifted.queue.create_upload(ucfg, provider_name, image_name, settings)[source]¶
    +lifted.queue.create_upload(ucfg, provider_name, image_name, settings)[source]¶

    Creates a new upload

    Parameters
    @@ -422,9 +422,9 @@ follows an expected pattern.

    -
    +
    -lifted.queue.delete_upload(ucfg, uuid)[source]¶
    +lifted.queue.delete_upload(ucfg, uuid)[source]¶

    Delete an upload

    Parameters
    @@ -436,9 +436,9 @@ follows an expected pattern.

    -
    +
    -lifted.queue.get_all_uploads(ucfg)[source]¶
    +lifted.queue.get_all_uploads(ucfg)[source]¶

    Get a list of all stored Upload objects

    Parameters
    @@ -453,9 +453,9 @@ follows an expected pattern.

    -
    +
    -lifted.queue.get_upload(ucfg, uuid, ignore_missing=False, ignore_corrupt=False)[source]¶
    +lifted.queue.get_upload(ucfg, uuid, ignore_missing=False, ignore_corrupt=False)[source]¶

    Get an Upload object by UUID

    Parameters
    @@ -478,9 +478,9 @@ follows an expected pattern.

    -
    +
    -lifted.queue.get_uploads(ucfg, uuids)[source]¶
    +lifted.queue.get_uploads(ucfg, uuids)[source]¶

    Gets a list of Upload objects from a list of upload UUIDs, ignoring missing or corrupt uploads

    @@ -499,9 +499,9 @@ missing or corrupt uploads

    -
    +
    -lifted.queue.ready_upload(ucfg, uuid, image_path)[source]¶
    +lifted.queue.ready_upload(ucfg, uuid, image_path)[source]¶

    Pass an image_path to an upload and mark it ready to execute

    Parameters
    @@ -514,9 +514,9 @@ missing or corrupt uploads

    -
    +
    -lifted.queue.reset_upload(ucfg, uuid, new_image_name=None, new_settings=None)[source]¶
    +lifted.queue.reset_upload(ucfg, uuid, new_image_name=None, new_settings=None)[source]¶

    Reset an upload so it can be attempted again

    Parameters
    @@ -530,9 +530,9 @@ missing or corrupt uploads

    -
    +
    -lifted.queue.start_upload_monitor(ucfg)[source]¶
    +lifted.queue.start_upload_monitor(ucfg)[source]¶

    Start a thread that manages the upload queue

    Parameters
    @@ -544,16 +544,16 @@ missing or corrupt uploads

    lifted.upload module¶

    -
    +
    -class lifted.upload.Upload(uuid=None, provider_name=None, playbook_path=None, image_name=None, settings=None, creation_time=None, upload_log=None, upload_pid=None, image_path=None, status_callback=None, status=None)[source]¶
    +class lifted.upload.Upload(uuid=None, provider_name=None, playbook_path=None, image_name=None, settings=None, creation_time=None, upload_log=None, upload_pid=None, image_path=None, status_callback=None, status=None)[source]¶

    Bases: object

    Represents an upload of an image to a cloud provider. Instances of this class are serialized as TOML and stored in the upload queue directory, which is /var/lib/lorax/upload/queue/ by default

    -
    +
    -cancel(status_callback=None)[source]¶
    +cancel(status_callback=None)[source]¶

    Cancel the upload. Sends a SIGINT to self.upload_pid.

    Parameters
    @@ -562,9 +562,9 @@ which is /var/lib/lorax/upload/queue/ by default

    -
    +
    -execute(status_callback=None)[source]¶
    +execute(status_callback=None)[source]¶

    Execute the upload. Meant to be called from a dedicated process so that the upload can be cancelled by sending a SIGINT to self.upload_pid.

    @@ -575,7 +575,7 @@ self.upload_pid.

    -
    +
    is_cancellable()[source]¶

    Is the upload in a cancellable state?

    @@ -589,9 +589,9 @@ self.upload_pid.

    -
    +
    -ready(image_path, status_callback)[source]¶
    +ready(image_path, status_callback)[source]¶

    Provide an image_path and mark the upload as ready to execute

    Parameters
    @@ -603,9 +603,9 @@ self.upload_pid.

    -
    +
    -reset(status_callback)[source]¶
    +reset(status_callback)[source]¶

    Reset the upload so it can be attempted again

    Parameters
    @@ -614,7 +614,7 @@ self.upload_pid.

    -
    +
    serializable()[source]¶

    Returns a representation of the object as a dict for serialization

    @@ -628,9 +628,9 @@ self.upload_pid.

    -
    +
    -set_status(status, status_callback=None)[source]¶
    +set_status(status, status_callback=None)[source]¶

    Sets the status of the upload with an optional callback

    Parameters
    @@ -642,7 +642,7 @@ self.upload_pid.

    -
    +
    summary()[source]¶

    Return a dict with useful information about the upload

    diff --git a/docs/html/livemedia-creator.html b/docs/html/livemedia-creator.html index 5d7389e6..be7bfd5c 100644 --- a/docs/html/livemedia-creator.html +++ b/docs/html/livemedia-creator.html @@ -8,7 +8,7 @@ - livemedia-creator — Lorax 33.2 documentation + livemedia-creator — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    @@ -228,34 +228,20 @@ you have the anaconda-tui package installed.

    usage: livemedia-creator [-h]
                              (--make-iso | --make-disk | --make-fsimage | --make-appliance | --make-ami | --make-tar | --make-tar-disk | --make-pxe-live | --make-ostree-live | --make-oci | --make-vagrant)
    -                         [--iso ISO] [--iso-only] [--iso-name ISO_NAME]
    -                         [--ks KS] [--image-only] [--no-virt] [--proxy PROXY]
    -                         [--anaconda-arg ANACONDA_ARGS]
    -                         [--armplatform ARMPLATFORM] [--location LOCATION]
    -                         [--logfile LOGFILE]
    -                         [--lorax-templates LORAX_TEMPLATES] [--tmp TMP]
    -                         [--resultdir RESULT_DIR] [--macboot] [--nomacboot]
    -                         [--extra-boot-args EXTRA_BOOT_ARGS]
    -                         [--disk-image DISK_IMAGE] [--keep-image]
    -                         [--fs-image FS_IMAGE] [--image-name IMAGE_NAME]
    -                         [--tar-disk-name TAR_DISK_NAME] [--fs-label FS_LABEL]
    -                         [--image-size-align IMAGE_SIZE_ALIGN]
    -                         [--image-type IMAGE_TYPE] [--qemu-arg QEMU_ARGS]
    -                         [--qcow2] [--qcow2-arg QEMU_ARGS]
    -                         [--compression COMPRESSION]
    -                         [--compress-arg COMPRESS_ARGS] [--app-name APP_NAME]
    -                         [--app-template APP_TEMPLATE] [--app-file APP_FILE]
    -                         [--ram MEMORY] [--vcpus VCPUS] [--vnc VNC]
    -                         [--arch ARCH] [--kernel-args KERNEL_ARGS]
    -                         [--ovmf-path OVMF_PATH] [--virt-uefi] [--no-kvm]
    -                         [--with-rng WITH_RNG] [--dracut-conf DRACUT_CONF]
    -                         [--dracut-arg DRACUT_ARGS]
    -                         [--live-rootfs-size LIVE_ROOTFS_SIZE]
    -                         [--live-rootfs-keep-size] [--oci-config OCI_CONFIG]
    -                         [--oci-runtime OCI_RUNTIME]
    -                         [--vagrant-metadata VAGRANT_METADATA]
    -                         [--vagrantfile VAGRANTFILE] [--project PROJECT]
    -                         [--releasever RELEASEVER] [--volid VOLID]
    +                         [--iso ISO] [--iso-only] [--iso-name ISO_NAME] [--ks KS] [--image-only] [--no-virt]
    +                         [--proxy PROXY] [--anaconda-arg ANACONDA_ARGS] [--armplatform ARMPLATFORM]
    +                         [--location LOCATION] [--logfile LOGFILE] [--lorax-templates LORAX_TEMPLATES] [--tmp TMP]
    +                         [--resultdir RESULT_DIR] [--macboot] [--nomacboot] [--extra-boot-args EXTRA_BOOT_ARGS]
    +                         [--disk-image DISK_IMAGE] [--keep-image] [--fs-image FS_IMAGE] [--image-name IMAGE_NAME]
    +                         [--tar-disk-name TAR_DISK_NAME] [--fs-label FS_LABEL] [--image-size-align IMAGE_SIZE_ALIGN]
    +                         [--image-type IMAGE_TYPE] [--qemu-arg QEMU_ARGS] [--qcow2] [--qcow2-arg QEMU_ARGS]
    +                         [--compression COMPRESSION] [--compress-arg COMPRESS_ARGS] [--app-name APP_NAME]
    +                         [--app-template APP_TEMPLATE] [--app-file APP_FILE] [--ram MEMORY] [--vcpus VCPUS]
    +                         [--vnc VNC] [--arch ARCH] [--kernel-args KERNEL_ARGS] [--ovmf-path OVMF_PATH] [--virt-uefi]
    +                         [--no-kvm] [--with-rng WITH_RNG] [--dracut-conf DRACUT_CONF] [--dracut-arg DRACUT_ARGS]
    +                         [--live-rootfs-size LIVE_ROOTFS_SIZE] [--live-rootfs-keep-size] [--oci-config OCI_CONFIG]
    +                         [--oci-runtime OCI_RUNTIME] [--vagrant-metadata VAGRANT_METADATA]
    +                         [--vagrantfile VAGRANTFILE] [--project PROJECT] [--releasever RELEASEVER] [--volid VOLID]
                              [--squashfs-only] [--timeout TIMEOUT] [-V]
     
    diff --git a/docs/html/lorax-composer.html b/docs/html/lorax-composer.html index ba6e9a97..1b01fead 100644 --- a/docs/html/lorax-composer.html +++ b/docs/html/lorax-composer.html @@ -8,7 +8,7 @@ - lorax-composer — Lorax 33.2 documentation + lorax-composer — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    @@ -204,13 +204,21 @@

    Brian C. Lane <bcl@redhat.com>

    -

    lorax-composer is an API server that allows you to build disk images using +

    lorax-composer is a WELDR API server that allows you to build disk images using Blueprints to describe the package versions to be installed into the image. It is compatible with the Weldr project's bdcs-api REST protocol. More information on Weldr can be found on the Weldr blog.

    Behind the scenes it uses livemedia-creator and Anaconda to handle the installation and configuration of the images.

    +
    +

    Note

    +

    lorax-composer is now deprecated. It is being replaced by the +osbuild-composer WELDR API server which implements more features (eg. +ostree, image uploads, etc.) You can still use composer-cli and +cockpit-composer with osbuild-composer. See the documentation or +the osbuild website for more information.

    +

    Important Things To Note¶

      @@ -280,10 +288,8 @@ images using lorax-

      lorax-composer cmdline arguments¶

      Lorax Composer API Server

      -
      usage: lorax-composer [-h] [--socket SOCKET] [--user USER] [--group GROUP]
      -                      [--log LOG] [--mockfiles MOCKFILES]
      -                      [--sharedir SHAREDIR] [-V] [-c CONFIG]
      -                      [--releasever STRING] [--tmp TMP] [--proxy PROXY]
      +
      usage: lorax-composer [-h] [--socket SOCKET] [--user USER] [--group GROUP] [--log LOG] [--mockfiles MOCKFILES]
      +                      [--sharedir SHAREDIR] [-V] [-c CONFIG] [--releasever STRING] [--tmp TMP] [--proxy PROXY]
                             [--no-system-repos]
                             BLUEPRINTS
       
      @@ -610,12 +616,12 @@ these are currently available via ./share/composer/. The name of the kickstart is what will be used by the /compose/types route, and the compose_type field of the POST to start a compose. It also needs to have -code added to the pylorax.api.compose.compose_args() function. The +code added to the pylorax.api.compose.compose_args() function. The _MAP entry in this function defines what lorax-composer will pass to pylorax.installer.novirt_install() when it runs the compose. When the compose is finished the output files need to be copied out of the build directory (/var/lib/lorax/composer/results/<UUID>/compose/), -pylorax.api.compose.move_compose_results() handles this for each type. +pylorax.api.compose.move_compose_results() handles this for each type. You should move them instead of copying to save space.

      If the new output type does not have support in livemedia-creator it should be added there first. This will make the output available to the widest number of @@ -627,8 +633,8 @@ via the --make-disk needs 3 things:

      • A partitioned-disk.ks file in ./share/composer/

      • -
      • A new entry in the _MAP in pylorax.api.compose.compose_args()

      • -
      • Add a bit of code to pylorax.api.compose.move_compose_results() to move the disk image from +

      • A new entry in the _MAP in pylorax.api.compose.compose_args()

      • +
      • Add a bit of code to pylorax.api.compose.move_compose_results() to move the disk image from the compose directory to the results directory.

      The partitioned-disk.ks is pretty similar to the example minimal kickstart diff --git a/docs/html/lorax.html b/docs/html/lorax.html index ecda8b47..6837c678 100644 --- a/docs/html/lorax.html +++ b/docs/html/lorax.html @@ -8,7 +8,7 @@ - Lorax — Lorax 33.2 documentation + Lorax — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@

      - 33.2 + 33.10
      @@ -204,20 +204,14 @@ repositories.

      lorax cmdline arguments¶

      Create the Anaconda boot.iso

      -
      usage: lorax [-h] -p PRODUCT -v VERSION -r RELEASE [-s REPOSITORY]
      -             [--repo REPOSITORY] [-m REPOSITORY] [-t VARIANT] [-b URL]
      -             [--isfinal] [-c CONFIGFILE] [--proxy HOST] [-i PACKAGE]
      -             [-e PACKAGE] [--buildarch ARCH] [--volid VOLID] [--macboot]
      -             [--nomacboot] [--noupgrade] [--logfile LOGFILE] [--tmp TMP]
      -             [--cachedir CACHEDIR] [--workdir WORKDIR] [--force]
      -             [--add-template ADD_TEMPLATES]
      -             [--add-template-var ADD_TEMPLATE_VARS]
      -             [--add-arch-template ADD_ARCH_TEMPLATES]
      -             [--add-arch-template-var ADD_ARCH_TEMPLATE_VARS] [--noverify]
      -             [--sharedir SHAREDIR] [--enablerepo [repo]]
      -             [--disablerepo [repo]] [--rootfs-size ROOTFS_SIZE]
      -             [--noverifyssl] [--dnfplugin DNFPLUGINS] [--squashfs-only]
      -             [--skip-branding] [--dracut-conf DRACUT_CONF]
      +
      usage: lorax [-h] -p PRODUCT -v VERSION -r RELEASE [-s REPOSITORY] [--repo REPOSITORY] [-m REPOSITORY] [-t VARIANT]
      +             [-b URL] [--isfinal] [-c CONFIGFILE] [--proxy HOST] [-i PACKAGE] [-e PACKAGE] [--buildarch ARCH]
      +             [--volid VOLID] [--macboot] [--nomacboot] [--noupgrade] [--logfile LOGFILE] [--tmp TMP]
      +             [--cachedir CACHEDIR] [--workdir WORKDIR] [--force] [--add-template ADD_TEMPLATES]
      +             [--add-template-var ADD_TEMPLATE_VARS] [--add-arch-template ADD_ARCH_TEMPLATES]
      +             [--add-arch-template-var ADD_ARCH_TEMPLATE_VARS] [--noverify] [--sharedir SHAREDIR]
      +             [--enablerepo [repo]] [--disablerepo [repo]] [--rootfs-size ROOTFS_SIZE] [--noverifyssl]
      +             [--dnfplugin DNFPLUGINS] [--squashfs-only] [--skip-branding] [--dracut-conf DRACUT_CONF]
                    [--dracut-arg DRACUT_ARGS] [-V]
                    OUTPUTDIR
       
      diff --git a/docs/html/mkksiso.html b/docs/html/mkksiso.html index 7d52dd10..2229dbd5 100644 --- a/docs/html/mkksiso.html +++ b/docs/html/mkksiso.html @@ -8,7 +8,7 @@ - mkksiso — Lorax 33.2 documentation + mkksiso — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
      - 33.2 + 33.10
      diff --git a/docs/html/modules.html b/docs/html/modules.html index 5128fd04..d5b589b1 100644 --- a/docs/html/modules.html +++ b/docs/html/modules.html @@ -8,7 +8,7 @@ - src — Lorax 33.2 documentation + src — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
      - 33.2 + 33.10
      diff --git a/docs/html/objects.inv b/docs/html/objects.inv index d4473a59..46d4d313 100644 Binary files a/docs/html/objects.inv and b/docs/html/objects.inv differ diff --git a/docs/html/product-images.html b/docs/html/product-images.html index 0372ff66..208dfd2f 100644 --- a/docs/html/product-images.html +++ b/docs/html/product-images.html @@ -8,7 +8,7 @@ - Product and Updates Images — Lorax 33.2 documentation + Product and Updates Images — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
      - 33.2 + 33.10
      diff --git a/docs/html/py-modindex.html b/docs/html/py-modindex.html index 29819917..75cefe80 100644 --- a/docs/html/py-modindex.html +++ b/docs/html/py-modindex.html @@ -8,7 +8,7 @@ - Python Module Index — Lorax 33.2 documentation + Python Module Index — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -61,7 +61,7 @@
      - 33.2 + 33.10
      diff --git a/docs/html/pylorax.api.html b/docs/html/pylorax.api.html index 7c33bb80..089dd76b 100644 --- a/docs/html/pylorax.api.html +++ b/docs/html/pylorax.api.html @@ -8,7 +8,7 @@ - pylorax.api package — Lorax 33.2 documentation + pylorax.api package — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -59,7 +59,7 @@
      - 33.2 + 33.10
      @@ -199,9 +199,9 @@

      pylorax.api.bisect module¶

      -
      +
      -pylorax.api.bisect.insort_left(a, x, key=None, lo=0, hi=None)[source]¶
      +pylorax.api.bisect.insort_left(a, x, key=None, lo=0, hi=None)[source]¶

      Insert item x in list a, and keep it sorted assuming a is sorted.

      Parameters
      @@ -229,15 +229,15 @@ was inserted.

      pylorax.api.checkparams module¶

      -
      +
      -pylorax.api.checkparams.checkparams(tuples)[source]¶
      +pylorax.api.checkparams.checkparams(tuples)[source]¶

      pylorax.api.cmdline module¶

      -
      +
      pylorax.api.cmdline.lorax_composer_parser()[source]¶

      Return the ArgumentParser for lorax-composer

      @@ -257,9 +257,9 @@ packages required by the output type, it should not have the trailing %end becau package NEVRAs will be appended to it at build time.

      compose_args should have a name matching the kickstart, and it should set the novirt_install parameters needed to generate the desired output. Other types should be set to False.

      -
      +
      -pylorax.api.compose.add_customizations(f, recipe)[source]¶
      +pylorax.api.compose.add_customizations(f, recipe)[source]¶

      Add customizations to the kickstart file

      Parameters
      @@ -277,9 +277,9 @@ parameters needed to generate the desired output. Other types should be set to F
      -
      +
      -pylorax.api.compose.bootloader_append(line, kernel_append)[source]¶
      +pylorax.api.compose.bootloader_append(line, kernel_append)[source]¶

      Insert the kernel_append string into the --append argument

      Parameters
      @@ -293,9 +293,9 @@ parameters needed to generate the desired output. Other types should be set to F is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.compose_args(compose_type)[source]¶
      +pylorax.api.compose.compose_args(compose_type)[source]¶

      Returns the settings to pass to novirt_install for the compose type

      Parameters
      @@ -307,18 +307,18 @@ These are the ones the define the type of output, it's filename, etc. Other options will be filled in by make_compose()

      -
      +
      -pylorax.api.compose.compose_types(share_dir)[source]¶
      +pylorax.api.compose.compose_types(share_dir)[source]¶

      Returns a list of tuples of the supported output types, and their state

      The output types come from the kickstart names in /usr/share/lorax/composer/*ks

      If they are disabled on the current arch their state is False. If enabled, it is True. eg. [("alibaba", False), ("ext4-filesystem", True), ...]

      -
      +
      -pylorax.api.compose.customize_ks_template(ks_template, recipe)[source]¶
      +pylorax.api.compose.customize_ks_template(ks_template, recipe)[source]¶

      Customize the kickstart template and return it

      Parameters
      @@ -335,9 +335,9 @@ Add bootloader line if it is missing.

      Add default timezone if needed. It does NOT replace an existing timezone entry

      -
      +
      -pylorax.api.compose.firewall_cmd(line, settings)[source]¶
      +pylorax.api.compose.firewall_cmd(line, settings)[source]¶

      Update the firewall line with the new ports and services

      Parameters
      @@ -351,9 +351,9 @@ Add bootloader line if it is missing.

      is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.get_default_services(recipe)[source]¶
      +pylorax.api.compose.get_default_services(recipe)[source]¶

      Get the default string for services, based on recipe :param recipe: The recipe

      @@ -369,9 +369,9 @@ so return an empty string. Otherwise return "services" which will be u the settings.

      -
      +
      -pylorax.api.compose.get_extra_pkgs(dbo, share_dir, compose_type)[source]¶
      +pylorax.api.compose.get_extra_pkgs(dbo, share_dir, compose_type)[source]¶

      Return extra packages needed for the output type

      Parameters
      @@ -395,9 +395,9 @@ iso using the templates such as x86.tmpl

      even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_firewall_settings(recipe)[source]¶
      +pylorax.api.compose.get_firewall_settings(recipe)[source]¶

      Return the customizations.firewall settings

      Parameters
      @@ -412,9 +412,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_kernel_append(recipe)[source]¶
      +pylorax.api.compose.get_kernel_append(recipe)[source]¶

      Return the customizations.kernel append value

      Parameters
      @@ -429,9 +429,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_keyboard_layout(recipe)[source]¶
      +pylorax.api.compose.get_keyboard_layout(recipe)[source]¶

      Return the customizations.locale.keyboard list

      Parameters
      @@ -446,9 +446,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_languages(recipe)[source]¶
      +pylorax.api.compose.get_languages(recipe)[source]¶

      Return the customizations.locale.languages list

      Parameters
      @@ -463,9 +463,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_services(recipe)[source]¶
      +pylorax.api.compose.get_services(recipe)[source]¶

      Return the customizations.services settings

      Parameters
      @@ -480,9 +480,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.get_timezone_settings(recipe)[source]¶
      +pylorax.api.compose.get_timezone_settings(recipe)[source]¶

      Return the customizations.timezone dict

      Parameters
      @@ -497,9 +497,9 @@ even though the results are applied differently.

      -
      +
      -pylorax.api.compose.keyboard_cmd(line, layout)[source]¶
      +pylorax.api.compose.keyboard_cmd(line, layout)[source]¶

      Update the keyboard line with the layout

      Parameters
      @@ -513,9 +513,9 @@ even though the results are applied differently.

      is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.lang_cmd(line, languages)[source]¶
      +pylorax.api.compose.lang_cmd(line, languages)[source]¶

      Update the lang line with the languages

      Parameters
      @@ -529,9 +529,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.move_compose_results(cfg, results_dir)[source]¶
      +pylorax.api.compose.move_compose_results(cfg, results_dir)[source]¶

      Move the final image to the results_dir and cleanup the unneeded compose files

      Parameters
      @@ -543,9 +543,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.repo_to_ks(r, url='url')[source]¶
      +pylorax.api.compose.repo_to_ks(r, url='url')[source]¶

      Return a kickstart line with the correct args. :param r: DNF repository information :type r: dnf.Repo @@ -556,9 +556,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      Set url to "baseurl" if it is a repo, leave it as "url" for the installation url.

      -
      +
      -pylorax.api.compose.services_cmd(line, settings)[source]¶
      +pylorax.api.compose.services_cmd(line, settings)[source]¶

      Update the services line with additional services to enable/disable

      Parameters
      @@ -572,9 +572,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_mode=0)[source]¶
      +pylorax.api.compose.start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_mode=0)[source]¶

      Start the build

      Parameters
      @@ -594,9 +594,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.test_templates(dbo, share_dir)[source]¶
      +pylorax.api.compose.test_templates(dbo, share_dir)[source]¶

      Try depsolving each of the the templates and report any errors

      Parameters
      @@ -612,9 +612,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      Return a list of templates and errors encountered or an empty list

      -
      +
      -pylorax.api.compose.timezone_cmd(line, settings)[source]¶
      +pylorax.api.compose.timezone_cmd(line, settings)[source]¶

      Update the timezone line with the settings

      Parameters
      @@ -628,9 +628,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      is parsed correctly, and re-assembled for inclusion into the final kickstart

      -
      +
      -pylorax.api.compose.write_ks_group(f, group)[source]¶
      +pylorax.api.compose.write_ks_group(f, group)[source]¶

      Write kickstart group entry

      Parameters
      @@ -643,9 +643,9 @@ is parsed correctly, and re-assembled for inclusion into the final kickstart

      gid is optional

      -
      +
      -pylorax.api.compose.write_ks_root(f, user)[source]¶
      +pylorax.api.compose.write_ks_root(f, user)[source]¶

      Write kickstart root password and sshkey entry

      Parameters
      @@ -667,9 +667,9 @@ If it contains password, use rootpw to set it

      for root.

      -
      +
      -pylorax.api.compose.write_ks_user(f, user)[source]¶
      +pylorax.api.compose.write_ks_user(f, user)[source]¶

      Write kickstart user and sshkey entry

      Parameters
      @@ -688,20 +688,20 @@ with whatever options are relevant.

      pylorax.api.config module¶

      -
      +
      -class pylorax.api.config.ComposerConfig(defaults=None, dict_type=<class 'collections.OrderedDict'>, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section='DEFAULT', interpolation=<object object>, converters=<object object>)[source]¶
      +class pylorax.api.config.ComposerConfig(defaults=None, dict_type=<class 'dict'>, allow_no_value=False, *, delimiters=('=', ':'), comment_prefixes=('#', ';'), inline_comment_prefixes=None, strict=True, empty_lines_in_values=True, default_section='DEFAULT', interpolation=<object object>, converters=<object object>)[source]¶

      Bases: configparser.ConfigParser

      -
      +
      -get_default(section, option, default)[source]¶
      +get_default(section, option, default)[source]¶
      -
      +
      -pylorax.api.config.configure(conf_file='/etc/lorax/composer.conf', root_dir='/', test_config=False)[source]¶
      +pylorax.api.config.configure(conf_file='/etc/lorax/composer.conf', root_dir='/', test_config=False)[source]¶

      lorax-composer configuration

      Parameters
      @@ -720,9 +720,9 @@ with whatever options are relevant.

      -
      +
      -pylorax.api.config.make_dnf_dirs(conf, uid, gid)[source]¶
      +pylorax.api.config.make_dnf_dirs(conf, uid, gid)[source]¶

      Make any missing dnf directories owned by user:group

      Parameters
      @@ -741,9 +741,9 @@ with whatever options are relevant.

      -
      +
      -pylorax.api.config.make_owned_dir(p_dir, uid, gid)[source]¶
      +pylorax.api.config.make_owned_dir(p_dir, uid, gid)[source]¶

      Make a directory and its parents, setting owner and group

      Parameters
      @@ -763,9 +763,9 @@ with whatever options are relevant.

      Check to make sure it does not have o+rw permissions and that it is owned by uid:gid

      -
      +
      -pylorax.api.config.make_queue_dirs(conf, gid)[source]¶
      +pylorax.api.config.make_queue_dirs(conf, gid)[source]¶

      Make any missing queue directories

      Parameters
      @@ -786,14 +786,14 @@ with whatever options are relevant.

      pylorax.api.dnfbase module¶

      -
      +
      -class pylorax.api.dnfbase.DNFLock(conf, expire_secs=21600)[source]¶
      +class pylorax.api.dnfbase.DNFLock(conf, expire_secs=21600)[source]¶

      Bases: object

      Hold the dnf.Base object and a Lock to control access to it.

      self.dbo is a property that returns the dnf.Base object, but it may change from one call to the next if the upstream repositories have changed.

      -
      +
      property lock¶

      Check for repo updates (using expiration time) and return the lock

      @@ -802,7 +802,7 @@ create a new one. This is the only way to force dnf to use the new metadata.

      -
      +
      property lock_check¶

      Force a check for repo updates and return the lock

      @@ -811,9 +811,9 @@ metadata.

      -
      +
      -pylorax.api.dnfbase.get_base_object(conf)[source]¶
      +pylorax.api.dnfbase.get_base_object(conf)[source]¶

      Get the DNF object with settings from the config file

      Parameters
      @@ -849,13 +849,13 @@ server.register_blueprint(v1, url_prefix="/api/v1/")

      This will register all of v0's routes under /api/v0, and all but /blueprints/list under /api/v1, and then register v1's version of /blueprints/list under /api/v1

      -
      +
      -class pylorax.api.flask_blueprint.BlueprintSetupStateSkip(blueprint, app, options, first_registration, skip_rules)[source]¶
      +class pylorax.api.flask_blueprint.BlueprintSetupStateSkip(blueprint, app, options, first_registration, skip_rules)[source]¶

      Bases: flask.blueprints.BlueprintSetupState

      -
      +
      -add_url_rule(rule, endpoint=None, view_func=None, **options)[source]¶
      +add_url_rule(rule, endpoint=None, view_func=None, **options)[source]¶

      A helper method to register a rule (and optionally a view function) to the application. The endpoint is automatically prefixed with the blueprint's name.

      @@ -863,13 +863,13 @@ blueprint's name.

      -
      +
      -class pylorax.api.flask_blueprint.BlueprintSkip(*args, **kwargs)[source]¶
      +class pylorax.api.flask_blueprint.BlueprintSkip(*args, **kwargs)[source]¶

      Bases: flask.blueprints.Blueprint

      -
      +
      -make_setup_state(app, options, first_registration=False)[source]¶
      +make_setup_state(app, options, first_registration=False)[source]¶

      Creates an instance of BlueprintSetupState() object that is later passed to the register callback functions. Subclasses can override this to return a subclass of the setup state.

      @@ -884,14 +884,14 @@ Subclasses can override this to return a subclass of the setup state.

      This module contains functions for cloning a git repo, creating a tar archive of the selected commit, branch, or tag, and packaging the files into an rpm that will be installed by anaconda when creating the image.

      -
      +
      -class pylorax.api.gitrpm.GitArchiveTarball(gitRepo)[source]¶
      +class pylorax.api.gitrpm.GitArchiveTarball(gitRepo)[source]¶

      Bases: object

      Create a git archive of the selected git repo and reference

      -
      +
      -write_file(sourcesDir)[source]¶
      +write_file(sourcesDir)[source]¶

      Create the tar archive

      Parameters
      @@ -904,14 +904,14 @@ The result is in RPMNAME.tar.xz under the sourcesDir

      -
      +
      -class pylorax.api.gitrpm.GitRpmBuild(*args, **kwargs)[source]¶
      -

      Bases: rpmfluff.SimpleRpmBuild

      +class pylorax.api.gitrpm.GitRpmBuild(*args, **kwargs)[source]¶ +

      Bases: rpmfluff.rpmbuild.SimpleRpmBuild

      Build an rpm containing files from a git repository

      -
      +
      -add_git_tarball(gitRepo)[source]¶
      +add_git_tarball(gitRepo)[source]¶

      Add a tar archive of a git repository to the rpm

      Parameters
      @@ -924,24 +924,24 @@ and sets up the rpm to install the archive contents into the destination path.

      -
      +
      check()[source]¶
      -
      +
      clean()[source]¶

      Remove the base directory from inside the tmpdir

      -
      +
      cleanup_tmpdir()[source]¶

      Remove the temporary directory and all of its contents

      -
      +
      get_base_dir()[source]¶

      Place all the files under a temporary directory + rpmbuild/

      @@ -949,9 +949,9 @@ path.

      -
      +
      -pylorax.api.gitrpm.create_gitrpm_repo(results_dir, recipe)[source]¶
      +pylorax.api.gitrpm.create_gitrpm_repo(results_dir, recipe)[source]¶

      Create a dnf repository with the rpms from the recipe

      Parameters
      @@ -973,9 +973,9 @@ on the dnf repository so that Anaconda can use it, and returns the path to the repository to the caller.

      -
      +
      -pylorax.api.gitrpm.get_repo_description(gitRepo)[source]¶
      +pylorax.api.gitrpm.get_repo_description(gitRepo)[source]¶

      Return a description including the git repo and reference

      Parameters
      @@ -990,9 +990,9 @@ repository to the caller.

      -
      +
      -pylorax.api.gitrpm.make_git_rpm(gitRepo, dest)[source]¶
      +pylorax.api.gitrpm.make_git_rpm(gitRepo, dest)[source]¶

      Create an rpm from the specified git repo

      Parameters
      @@ -1025,15 +1025,15 @@ directory. The gitRepo dict should have the following fields:

      pylorax.api.projects module¶

      -
      +
      exception pylorax.api.projects.ProjectsError[source]¶

      Bases: Exception

      -
      +
      -pylorax.api.projects.api_changelog(changelog)[source]¶
      +pylorax.api.projects.api_changelog(changelog)[source]¶

      Convert the changelog to a string

      Parameters
      @@ -1049,9 +1049,9 @@ directory. The gitRepo dict should have the following fields:

      This returns only the most recent changelog entry.

      -
      +
      -pylorax.api.projects.api_time(t)[source]¶
      +pylorax.api.projects.api_time(t)[source]¶

      Convert time since epoch to a string

      Parameters
      @@ -1066,9 +1066,9 @@ directory. The gitRepo dict should have the following fields:

      -
      +
      -pylorax.api.projects.delete_repo_source(source_glob, source_id)[source]¶
      +pylorax.api.projects.delete_repo_source(source_glob, source_id)[source]¶

      Delete a source from a repo file

      Parameters
      @@ -1090,9 +1090,9 @@ If it is the last one in the file, delete the file.

      source_id isn't passed to it.

      -
      +
      -pylorax.api.projects.dep_evra(dep)[source]¶
      +pylorax.api.projects.dep_evra(dep)[source]¶

      Return the epoch:version-release.arch for the dep

      Parameters
      @@ -1107,15 +1107,15 @@ source_id isn't passed to it.

      -
      +
      -pylorax.api.projects.dep_nevra(dep)[source]¶
      +pylorax.api.projects.dep_nevra(dep)[source]¶

      Return the name-epoch:version-release.arch

      -
      +
      -pylorax.api.projects.dnf_repo_to_file_repo(repo)[source]¶
      +pylorax.api.projects.dnf_repo_to_file_repo(repo)[source]¶

      Return a string representation of a DNF Repo object suitable for writing to a .repo file

      Parameters
      @@ -1133,9 +1133,9 @@ it ouputs baseurl and gpgkey as python lists which DNF cannot read. So do this m only the attributes we care about.

      -
      +
      -pylorax.api.projects.estimate_size(packages, block_size=6144)[source]¶
      +pylorax.api.projects.estimate_size(packages, block_size=6144)[source]¶

      Estimate the installed size of a package list

      Parameters
      @@ -1156,9 +1156,9 @@ dnf doesn't provide access to. So use the file count and block size to estimate a minimum size for each package.

      -
      +
      -pylorax.api.projects.get_repo_sources(source_glob)[source]¶
      +pylorax.api.projects.get_repo_sources(source_glob)[source]¶

      Return a list of sources from a directory of yum repositories

      Parameters
      @@ -1173,9 +1173,9 @@ a minimum size for each package.

      -
      +
      -pylorax.api.projects.get_source_ids(source_path)[source]¶
      +pylorax.api.projects.get_source_ids(source_path)[source]¶

      Return a list of the source ids in a file

      Parameters
      @@ -1190,9 +1190,9 @@ a minimum size for each package.

      -
      +
      -pylorax.api.projects.modules_info(dbo, module_names)[source]¶
      +pylorax.api.projects.modules_info(dbo, module_names)[source]¶

      Return details about a module, including dependencies

      Parameters
      @@ -1210,9 +1210,9 @@ a minimum size for each package.

      -
      +
      -pylorax.api.projects.modules_list(dbo, module_names)[source]¶
      +pylorax.api.projects.modules_list(dbo, module_names)[source]¶

      Return a list of modules

      Parameters
      @@ -1233,9 +1233,9 @@ a minimum size for each package.

      and sets the type to "rpm"

      -
      +
      -pylorax.api.projects.new_repo_source(dbo, repoid, source, repo_dir)[source]¶
      +pylorax.api.projects.new_repo_source(dbo, repoid, source, repo_dir)[source]¶

      Add a new repo source from a Weldr source dict

      Parameters
      @@ -1257,9 +1257,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      DNF variables will be substituted at load time, and on restart.

      -
      +
      -pylorax.api.projects.pkg_to_build(pkg)[source]¶
      +pylorax.api.projects.pkg_to_build(pkg)[source]¶

      Extract the build details from a hawkey.Package object

      Parameters
      @@ -1276,9 +1276,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      Note that this only returns the build dict, it does not include the name, description, etc.

      -
      +
      -pylorax.api.projects.pkg_to_dep(pkg)[source]¶
      +pylorax.api.projects.pkg_to_dep(pkg)[source]¶

      Extract the info from a hawkey.Package object

      Parameters
      @@ -1293,9 +1293,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'
      -
      +
      -pylorax.api.projects.pkg_to_project(pkg)[source]¶
      +pylorax.api.projects.pkg_to_project(pkg)[source]¶

      Extract the details from a hawkey.Package object

      Parameters
      @@ -1311,9 +1311,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      upstream_vcs is hard-coded to UPSTREAM_VCS

      -
      +
      -pylorax.api.projects.pkg_to_project_info(pkg)[source]¶
      +pylorax.api.projects.pkg_to_project_info(pkg)[source]¶

      Extract the details from a hawkey.Package object

      Parameters
      @@ -1329,9 +1329,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      metadata entries are hard-coded to {}

      -
      +
      -pylorax.api.projects.proj_to_module(proj)[source]¶
      +pylorax.api.projects.proj_to_module(proj)[source]¶

      Extract the name from a project_info dict

      Parameters
      @@ -1347,9 +1347,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      group_type is hard-coded to "rpm"

      -
      +
      -pylorax.api.projects.projects_depsolve(dbo, projects, groups)[source]¶
      +pylorax.api.projects.projects_depsolve(dbo, projects, groups)[source]¶

      Return the dependencies for a list of projects

      Parameters
      @@ -1371,9 +1371,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'
      -
      +
      -pylorax.api.projects.projects_depsolve_with_size(dbo, projects, groups, with_core=True)[source]¶
      +pylorax.api.projects.projects_depsolve_with_size(dbo, projects, groups, with_core=True)[source]¶

      Return the dependencies and installed size for a list of projects

      Parameters
      @@ -1395,9 +1395,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'
      -
      +
      -pylorax.api.projects.projects_info(dbo, project_names)[source]¶
      +pylorax.api.projects.projects_info(dbo, project_names)[source]¶

      Return details about specific projects

      Parameters
      @@ -1416,9 +1416,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'

      If project_names is None it will return the full list of available packages

      -
      +
      -pylorax.api.projects.projects_list(dbo)[source]¶
      +pylorax.api.projects.projects_list(dbo)[source]¶

      Return a list of projects

      Parameters
      @@ -1433,9 +1433,9 @@ The id parameter will the the 'name' field for API v0, and the 'id'
      -
      +
      -pylorax.api.projects.repo_to_source(repo, system_source, api=1)[source]¶
      +pylorax.api.projects.repo_to_source(repo, system_source, api=1)[source]¶

      Return a Weldr Source dict created from the DNF Repository

      Parameters
      @@ -1473,9 +1473,9 @@ In v0 of the API na id has been added for the repo.id

      -
      +
      -pylorax.api.projects.source_to_repo(source, dnf_conf)[source]¶
      +pylorax.api.projects.source_to_repo(source, dnf_conf)[source]¶

      Return a dnf Repo object created from a source dict

      Parameters
      @@ -1511,9 +1511,9 @@ In v0 of the API na v0 of the API only used name, v1 added the distinction between id and name.

      -
      +
      -pylorax.api.projects.source_to_repodict(source)[source]¶
      +pylorax.api.projects.source_to_repodict(source)[source]¶

      Return a tuple suitable for use with dnf.add_new_repo

      Parameters
      @@ -1534,9 +1534,9 @@ with dnf.repos.add_new_repo

      pylorax.api.queue module¶

      Functions to monitor compose queue and run anaconda

      -
      +
      -pylorax.api.queue.build_status(cfg, status_filter=None, api=1)[source]¶
      +pylorax.api.queue.build_status(cfg, status_filter=None, api=1)[source]¶

      Return the details of finished or failed builds

      Parameters
      @@ -1558,9 +1558,9 @@ system. It does not return the status of builds that have not been finished. Use queue_status() for those.

      -
      +
      -pylorax.api.queue.check_queues(cfg)[source]¶
      +pylorax.api.queue.check_queues(cfg)[source]¶

      Check to make sure the new and run queue symlinks are correct

      Parameters
      @@ -1571,9 +1571,9 @@ Use queue_status() for those.

      set in STATUS have a symlink in queue/new/

      -
      +
      -pylorax.api.queue.compose_detail(cfg, results_dir, api=1)[source]¶
      +pylorax.api.queue.compose_detail(cfg, results_dir, api=1)[source]¶

      Return details about the build.

      Parameters
      @@ -1613,9 +1613,9 @@ None in Python (or null in JSON). The following timestamps are included:

    -
    +
    -pylorax.api.queue.get_compose_type(results_dir)[source]¶
    +pylorax.api.queue.get_compose_type(results_dir)[source]¶

    Return the type of composition.

    Parameters
    @@ -1633,9 +1633,9 @@ None in Python (or null in JSON). The following timestamps are included:

    -
    +
    -pylorax.api.queue.get_image_name(uuid_dir)[source]¶
    +pylorax.api.queue.get_image_name(uuid_dir)[source]¶

    Return the filename and full path of the build's image file

    Parameters
    @@ -1653,9 +1653,9 @@ None in Python (or null in JSON). The following timestamps are included:

    -
    +
    -pylorax.api.queue.make_compose(cfg, results_dir)[source]¶
    +pylorax.api.queue.make_compose(cfg, results_dir)[source]¶

    Run anaconda with the final-kickstart.ks from results_dir

    Parameters
    @@ -1679,9 +1679,9 @@ moved into logs/anaconda/ and their ownership will be set to the user from the c object.

    -
    +
    -pylorax.api.queue.monitor(cfg)[source]¶
    +pylorax.api.queue.monitor(cfg)[source]¶

    Monitor the queue for new compose requests

    Parameters
    @@ -1701,9 +1701,9 @@ will be created in the results directory.

    from ./queue/run/ to ./queue/new/ and rerun them.

    -
    +
    -pylorax.api.queue.queue_status(cfg, api=1)[source]¶
    +pylorax.api.queue.queue_status(cfg, api=1)[source]¶

    Return details about what is in the queue.

    Parameters
    @@ -1723,9 +1723,9 @@ from ./queue/run/ to ./queue/new/ and rerun them.

    and "run" has the uuids that are being built (currently limited to 1 at a time).

    -
    +
    -pylorax.api.queue.start_queue_monitor(cfg, uid, gid)[source]¶
    +pylorax.api.queue.start_queue_monitor(cfg, uid, gid)[source]¶

    Start the queue monitor as a mp process

    Parameters
    @@ -1741,9 +1741,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_add_upload(cfg, uuid, upload_uuid)[source]¶
    +pylorax.api.queue.uuid_add_upload(cfg, uuid, upload_uuid)[source]¶

    Add an upload UUID to a build

    Parameters
    @@ -1762,9 +1762,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_cancel(cfg, uuid)[source]¶
    +pylorax.api.queue.uuid_cancel(cfg, uuid)[source]¶

    Cancel a build and delete its results

    Parameters
    @@ -1783,9 +1783,9 @@ and "run" has the uuids that are being built (currently limited to 1 a

    Only call this if the build status is WAITING or RUNNING

    -
    +
    -pylorax.api.queue.uuid_delete(cfg, uuid)[source]¶
    +pylorax.api.queue.uuid_delete(cfg, uuid)[source]¶

    Delete all of the results from a compose

    Parameters
    @@ -1806,9 +1806,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_get_uploads(cfg, uuid)[source]¶
    +pylorax.api.queue.uuid_get_uploads(cfg, uuid)[source]¶

    Return the list of uploads for a build uuid

    Parameters
    @@ -1826,9 +1826,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_image(cfg, uuid)[source]¶
    +pylorax.api.queue.uuid_image(cfg, uuid)[source]¶

    Return the filename and full path of the build's image file

    Parameters
    @@ -1849,9 +1849,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_info(cfg, uuid, api=1)[source]¶
    +pylorax.api.queue.uuid_info(cfg, uuid, api=1)[source]¶

    Return information about the composition

    Parameters
    @@ -1882,9 +1882,9 @@ and "run" has the uuids that are being built (currently limited to 1 a
    -
    +
    -pylorax.api.queue.uuid_log(cfg, uuid, size=1024)[source]¶
    +pylorax.api.queue.uuid_log(cfg, uuid, size=1024)[source]¶

    Return size KiB from the end of the most currently relevant log for a given compose

    @@ -1911,9 +1911,9 @@ compose. It tries to return lines from the end of the log, it will attempt to start on a line boundary, and it may return less than size kbytes.

    -
    +
    -pylorax.api.queue.uuid_ready_upload(cfg, uuid, upload_uuid)[source]¶
    +pylorax.api.queue.uuid_ready_upload(cfg, uuid, upload_uuid)[source]¶

    Set an upload to READY if the build is in FINISHED state

    Parameters
    @@ -1935,9 +1935,9 @@ to start on a line boundary, and it may return less than size kbyte
    -
    +
    -pylorax.api.queue.uuid_remove_upload(cfg, upload_uuid)[source]¶
    +pylorax.api.queue.uuid_remove_upload(cfg, upload_uuid)[source]¶

    Remove an upload UUID from the build

    Parameters
    @@ -1958,9 +1958,9 @@ to start on a line boundary, and it may return less than size kbyte
    -
    +
    -pylorax.api.queue.uuid_schedule_upload(cfg, uuid, provider_name, image_name, settings)[source]¶
    +pylorax.api.queue.uuid_schedule_upload(cfg, uuid, provider_name, image_name, settings)[source]¶

    Schedule an upload of an image

    Parameters
    @@ -1984,9 +1984,9 @@ to start on a line boundary, and it may return less than size kbyte
    -
    +
    -pylorax.api.queue.uuid_status(cfg, uuid, api=1)[source]¶
    +pylorax.api.queue.uuid_status(cfg, uuid, api=1)[source]¶

    Return the details of a specific UUID compose

    Parameters
    @@ -2006,9 +2006,9 @@ to start on a line boundary, and it may return less than size kbyte

    Returns the same dict as compose_detail()

    -
    +
    -pylorax.api.queue.uuid_tar(cfg, uuid, metadata=False, image=False, logs=False)[source]¶
    +pylorax.api.queue.uuid_tar(cfg, uuid, metadata=False, image=False, logs=False)[source]¶

    Return a tar of the build data

    Parameters
    @@ -2037,21 +2037,21 @@ the selected data to the caller by returning the Popen stdout from the tar proce

    pylorax.api.recipes module¶

    -
    +
    -class pylorax.api.recipes.CommitDetails(commit, timestamp, message, revision=None)[source]¶
    +class pylorax.api.recipes.CommitDetails(commit, timestamp, message, revision=None)[source]¶

    Bases: pylorax.base.DataHolder

    -
    +
    exception pylorax.api.recipes.CommitTimeValError[source]¶

    Bases: Exception

    -
    +
    -pylorax.api.recipes.NewRecipeGit(toml_dict)[source]¶
    +pylorax.api.recipes.NewRecipeGit(toml_dict)[source]¶

    Create a RecipeGit object from fields in a TOML dict

    Parameters
    @@ -2087,17 +2087,17 @@ the selected data to the caller by returning the Popen stdout from the tar proce

    Currently there is no support for authentication

    -
    +
    -class pylorax.api.recipes.Recipe(name, description, version, modules, packages, groups, customizations=None, gitrepos=None)[source]¶
    +class pylorax.api.recipes.Recipe(name, description, version, modules, packages, groups, customizations=None, gitrepos=None)[source]¶

    Bases: dict

    A Recipe of package and modules

    This is a subclass of dict that enforces the constructor arguments and adds a .filename property to return the recipe's filename, and a .toml() function to return the recipe as a TOML string.

    -
    +
    -bump_version(old_version=None)[source]¶
    +bump_version(old_version=None)[source]¶

    semver recipe version number bump

    Parameters
    @@ -2120,16 +2120,16 @@ If the old and new versions are the same, bump the patch level If they are different, check and return the new version

    -
    +
    property filename¶

    Return the Recipe's filename

    Replaces spaces in the name with '-' and appends .toml

    -
    +
    -freeze(deps)[source]¶
    +freeze(deps)[source]¶

    Return a new Recipe with full module and package NEVRA

    Parameters
    @@ -2144,37 +2144,37 @@ If they are different, check and return the new version

    -
    +
    property group_names¶

    Return the names of the groups. Groups do not have versions.

    -
    +
    property module_names¶

    Return the names of the modules

    -
    +
    property module_nver¶

    Return the names and version globs of the modules

    -
    +
    property package_names¶

    Return the names of the packages

    -
    +
    property package_nver¶

    Return the names and version globs of the packages

    -
    +
    toml()[source]¶

    Return the Recipe in TOML format

    @@ -2182,45 +2182,45 @@ If they are different, check and return the new version

    -
    +
    exception pylorax.api.recipes.RecipeError[source]¶

    Bases: Exception

    -
    +
    exception pylorax.api.recipes.RecipeFileError[source]¶

    Bases: Exception

    -
    +
    -class pylorax.api.recipes.RecipeGit(rpmname, rpmversion, rpmrelease, summary, repo, ref, destination)[source]¶
    +class pylorax.api.recipes.RecipeGit(rpmname, rpmversion, rpmrelease, summary, repo, ref, destination)[source]¶

    Bases: dict

    -
    +
    -class pylorax.api.recipes.RecipeGroup(name)[source]¶
    +class pylorax.api.recipes.RecipeGroup(name)[source]¶

    Bases: dict

    -
    +
    -class pylorax.api.recipes.RecipeModule(name, version)[source]¶
    +class pylorax.api.recipes.RecipeModule(name, version)[source]¶

    Bases: dict

    -
    +
    -class pylorax.api.recipes.RecipePackage(name, version)[source]¶
    +class pylorax.api.recipes.RecipePackage(name, version)[source]¶

    Bases: pylorax.api.recipes.RecipeModule

    -
    +
    -pylorax.api.recipes.check_list_case(expected_keys, recipe_keys, prefix='')[source]¶
    +pylorax.api.recipes.check_list_case(expected_keys, recipe_keys, prefix='')[source]¶

    Check the case of the recipe keys

    Parameters
    @@ -2238,9 +2238,9 @@ If they are different, check and return the new version

    -
    +
    -pylorax.api.recipes.check_recipe_dict(recipe_dict)[source]¶
    +pylorax.api.recipes.check_recipe_dict(recipe_dict)[source]¶

    Check a dict before using it to create a new Recipe

    Parameters
    @@ -2263,9 +2263,9 @@ are of the correct format, when included.

    a string that can be presented to users.

    -
    +
    -pylorax.api.recipes.check_required_list(lst, fields)[source]¶
    +pylorax.api.recipes.check_required_list(lst, fields)[source]¶

    Check a list of dicts for required fields

    Parameters
    @@ -2283,9 +2283,9 @@ a string that can be presented to users.

    -
    +
    -pylorax.api.recipes.commit_recipe(repo, branch, recipe)[source]¶
    +pylorax.api.recipes.commit_recipe(repo, branch, recipe)[source]¶

    Commit a recipe to a branch

    Parameters
    @@ -2307,9 +2307,9 @@ a string that can be presented to users.

    -
    +
    -pylorax.api.recipes.commit_recipe_directory(repo, branch, directory)[source]¶
    +pylorax.api.recipes.commit_recipe_directory(repo, branch, directory)[source]¶

    Commit all *.toml files from a directory, if they aren't already in git.

    Parameters
    @@ -2330,9 +2330,9 @@ a string that can be presented to users.

    be tried.

    -
    +
    -pylorax.api.recipes.commit_recipe_file(repo, branch, filename)[source]¶
    +pylorax.api.recipes.commit_recipe_file(repo, branch, filename)[source]¶

    Commit a recipe file to a branch

    Parameters
    @@ -2354,15 +2354,15 @@ be tried.

    -
    +
    -pylorax.api.recipes.customizations_diff(old_recipe, new_recipe)[source]¶
    +pylorax.api.recipes.customizations_diff(old_recipe, new_recipe)[source]¶

    Diff the customizations sections from two versions of a recipe

    -
    +
    -pylorax.api.recipes.delete_file(repo, branch, filename)[source]¶
    +pylorax.api.recipes.delete_file(repo, branch, filename)[source]¶

    Delete a file from a branch.

    Parameters
    @@ -2384,9 +2384,9 @@ be tried.

    -
    +
    -pylorax.api.recipes.delete_recipe(repo, branch, recipe_name)[source]¶
    +pylorax.api.recipes.delete_recipe(repo, branch, recipe_name)[source]¶

    Delete a recipe from a branch.

    Parameters
    @@ -2408,9 +2408,9 @@ be tried.

    -
    +
    -pylorax.api.recipes.diff_lists(title, field, old_items, new_items)[source]¶
    +pylorax.api.recipes.diff_lists(title, field, old_items, new_items)[source]¶

    Return the differences between two lists of dicts.

    Parameters
    @@ -2430,9 +2430,9 @@ be tried.

    -
    +
    -pylorax.api.recipes.find_commit_tag(repo, branch, filename, commit_id)[source]¶
    +pylorax.api.recipes.find_commit_tag(repo, branch, filename, commit_id)[source]¶

    Find the tag that matches the commit_id

    Parameters
    @@ -2455,9 +2455,9 @@ be a tag at all.

    The tag will look like: 'refs/tags/<branch>/<filename>/r<revision>'

    -
    +
    -pylorax.api.recipes.find_field_value(field, value, lst)[source]¶
    +pylorax.api.recipes.find_field_value(field, value, lst)[source]¶

    Find a field matching value in the list of dicts.

    Parameters
    @@ -2479,9 +2479,9 @@ be a tag at all.

    find_field_value("name", "one", lst) will return the matching dict.

    -
    +
    -pylorax.api.recipes.find_name(name, lst)[source]¶
    +pylorax.api.recipes.find_name(name, lst)[source]¶

    Find the dict matching the name in a list and return it.

    Parameters
    @@ -2500,9 +2500,9 @@ be a tag at all.

    This is just a wrapper for find_field_value with field set to "name"

    -
    +
    -pylorax.api.recipes.find_recipe_obj(path, recipe, default=None)[source]¶
    +pylorax.api.recipes.find_recipe_obj(path, recipe, default=None)[source]¶

    Find a recipe object

    Parameters
    @@ -2519,9 +2519,9 @@ return the default if it doesn't exist.

    find_recipe_obj(["customizations", "hostname"], recipe, "")

    -
    +
    -pylorax.api.recipes.get_commit_details(commit, revision=None)[source]¶
    +pylorax.api.recipes.get_commit_details(commit, revision=None)[source]¶

    Return the details about a specific commit.

    Parameters
    @@ -2542,9 +2542,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.get_revision_from_tag(tag)[source]¶
    +pylorax.api.recipes.get_revision_from_tag(tag)[source]¶

    Return the revision number from a tag

    Parameters
    @@ -2560,15 +2560,15 @@ return the default if it doesn't exist.

    The revision is the part after the r in 'branch/filename/rXXX'

    -
    +
    -pylorax.api.recipes.gfile(path)[source]¶
    +pylorax.api.recipes.gfile(path)[source]¶

    Convert a string path to GFile for use with Git

    -
    +
    -pylorax.api.recipes.head_commit(repo, branch)[source]¶
    +pylorax.api.recipes.head_commit(repo, branch)[source]¶

    Get the branch's HEAD Commit Object

    Parameters
    @@ -2589,9 +2589,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.is_commit_tag(repo, commit_id, tag)[source]¶
    +pylorax.api.recipes.is_commit_tag(repo, commit_id, tag)[source]¶

    Check to see if a tag points to a specific commit.

    Parameters
    @@ -2610,9 +2610,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.is_parent_diff(repo, filename, tree, parent)[source]¶
    +pylorax.api.recipes.is_parent_diff(repo, filename, tree, parent)[source]¶

    Check to see if the commit is different from its parents

    Parameters
    @@ -2632,9 +2632,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.list_branch_files(repo, branch)[source]¶
    +pylorax.api.recipes.list_branch_files(repo, branch)[source]¶

    Return a sorted list of the files on the branch HEAD

    Parameters
    @@ -2655,9 +2655,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.list_commit_files(repo, commit)[source]¶
    +pylorax.api.recipes.list_commit_files(repo, commit)[source]¶

    Return a sorted list of the files on a commit

    Parameters
    @@ -2678,9 +2678,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.list_commits(repo, branch, filename, limit=0)[source]¶
    +pylorax.api.recipes.list_commits(repo, branch, filename, limit=0)[source]¶

    List the commit history of a file on a branch.

    Parameters
    @@ -2703,9 +2703,9 @@ return the default if it doesn't exist.

    -
    +
    -pylorax.api.recipes.open_or_create_repo(path)[source]¶
    +pylorax.api.recipes.open_or_create_repo(path)[source]¶

    Open an existing repo, or create a new one

    Parameters
    @@ -2726,9 +2726,9 @@ If a repo already exists it will be opened and returned instead of creating a new one.

    -
    +
    -pylorax.api.recipes.prepare_commit(repo, branch, builder)[source]¶
    +pylorax.api.recipes.prepare_commit(repo, branch, builder)[source]¶

    Prepare for a commit

    Parameters
    @@ -2750,9 +2750,9 @@ creating a new one.

    -
    +
    -pylorax.api.recipes.read_commit(repo, branch, filename, commit=None)[source]¶
    +pylorax.api.recipes.read_commit(repo, branch, filename, commit=None)[source]¶

    Return the contents of a file on a specific branch or commit.

    Parameters
    @@ -2777,9 +2777,9 @@ creating a new one.

    commit:filename

    -
    +
    -pylorax.api.recipes.read_commit_spec(repo, spec)[source]¶
    +pylorax.api.recipes.read_commit_spec(repo, spec)[source]¶

    Return the raw content of the blob specified by the spec

    Parameters
    @@ -2801,9 +2801,9 @@ commit:filename

    eg. To read the README file from master the spec is "master:README"

    -
    +
    -pylorax.api.recipes.read_recipe_and_id(repo, branch, recipe_name, commit=None)[source]¶
    +pylorax.api.recipes.read_recipe_and_id(repo, branch, recipe_name, commit=None)[source]¶

    Read a recipe commit and its id from git

    Parameters
    @@ -2828,9 +2828,9 @@ commit:filename

    commit:filename

    -
    +
    -pylorax.api.recipes.read_recipe_commit(repo, branch, recipe_name, commit=None)[source]¶
    +pylorax.api.recipes.read_recipe_commit(repo, branch, recipe_name, commit=None)[source]¶

    Read a recipe commit from git and return a Recipe object

    Parameters
    @@ -2855,9 +2855,9 @@ commit:filename

    commit:filename

    -
    +
    -pylorax.api.recipes.recipe_diff(old_recipe, new_recipe)[source]¶
    +pylorax.api.recipes.recipe_diff(old_recipe, new_recipe)[source]¶

    Diff two versions of a recipe

    Parameters
    @@ -2875,16 +2875,16 @@ commit:filename

    -
    +
    -pylorax.api.recipes.recipe_filename(name)[source]¶
    +pylorax.api.recipes.recipe_filename(name)[source]¶

    Return the toml filename for a recipe

    Replaces spaces with '-' and appends '.toml'

    -
    +
    -pylorax.api.recipes.recipe_from_dict(recipe_dict)[source]¶
    +pylorax.api.recipes.recipe_from_dict(recipe_dict)[source]¶

    Create a Recipe object from a plain dict.

    Parameters
    @@ -2902,9 +2902,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.recipe_from_file(recipe_path)[source]¶
    +pylorax.api.recipes.recipe_from_file(recipe_path)[source]¶

    Return a recipe file as a Recipe object

    Parameters
    @@ -2919,9 +2919,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.recipe_from_toml(recipe_str)[source]¶
    +pylorax.api.recipes.recipe_from_toml(recipe_str)[source]¶

    Create a Recipe object from a toml string.

    Parameters
    @@ -2939,9 +2939,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.repo_file_exists(repo, branch, filename)[source]¶
    +pylorax.api.recipes.repo_file_exists(repo, branch, filename)[source]¶

    Return True if the filename exists on the branch

    Parameters
    @@ -2960,9 +2960,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.revert_file(repo, branch, filename, commit)[source]¶
    +pylorax.api.recipes.revert_file(repo, branch, filename, commit)[source]¶

    Revert the contents of a file to that of a previous commit

    Parameters
    @@ -2985,9 +2985,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.revert_recipe(repo, branch, recipe_name, commit)[source]¶
    +pylorax.api.recipes.revert_recipe(repo, branch, recipe_name, commit)[source]¶

    Revert the contents of a recipe to that of a previous commit

    Parameters
    @@ -3010,9 +3010,9 @@ commit:filename

    -
    +
    -pylorax.api.recipes.tag_file_commit(repo, branch, filename)[source]¶
    +pylorax.api.recipes.tag_file_commit(repo, branch, filename)[source]¶

    Tag a file's most recent commit

    Parameters
    @@ -3038,9 +3038,9 @@ Revisions start at 1 and increment for each new commit that is tagged. If the commit has already been tagged it will return false.

    -
    +
    -pylorax.api.recipes.tag_recipe_commit(repo, branch, recipe_name)[source]¶
    +pylorax.api.recipes.tag_recipe_commit(repo, branch, recipe_name)[source]¶

    Tag a file's most recent commit

    Parameters
    @@ -3063,9 +3063,9 @@ If the commit has already been tagged it will return false.

    Uses tag_file_commit()

    -
    +
    -pylorax.api.recipes.write_commit(repo, branch, filename, message, content)[source]¶
    +pylorax.api.recipes.write_commit(repo, branch, filename, message, content)[source]¶

    Make a new commit to a repository's branch

    Parameters
    @@ -3095,25 +3095,25 @@ If the commit has already been tagged it will return false.

    pylorax.api.server module¶

    -
    +
    -class pylorax.api.server.GitLock(repo, lock, dir)¶
    +class pylorax.api.server.GitLock(repo, lock, dir)¶

    Bases: tuple

    -
    +
    -property dir¶
    +dir¶

    Alias for field number 2

    -
    +
    -property lock¶
    +lock¶

    Alias for field number 1

    -
    +
    -property repo¶
    +repo¶

    Alias for field number 0

    @@ -3122,52 +3122,52 @@ If the commit has already been tagged it will return false.

    pylorax.api.timestamp module¶

    -
    +
    -pylorax.api.timestamp.timestamp_dict(destdir)[source]¶
    +pylorax.api.timestamp.timestamp_dict(destdir)[source]¶
    -
    +
    -pylorax.api.timestamp.write_timestamp(destdir, ty)[source]¶
    +pylorax.api.timestamp.write_timestamp(destdir, ty)[source]¶

    pylorax.api.toml module¶

    -
    +
    -exception pylorax.api.toml.TomlError(msg, doc, pos)[source]¶
    +exception pylorax.api.toml.TomlError(msg, doc, pos)[source]¶

    Bases: toml.decoder.TomlDecodeError

    -
    +
    -pylorax.api.toml.dump(o, file)[source]¶
    +pylorax.api.toml.dump(o, file)[source]¶
    -
    +
    -pylorax.api.toml.dumps(o)[source]¶
    +pylorax.api.toml.dumps(o)[source]¶
    -
    +
    -pylorax.api.toml.load(file)[source]¶
    +pylorax.api.toml.load(file)[source]¶
    -
    +
    -pylorax.api.toml.loads(s)[source]¶
    +pylorax.api.toml.loads(s)[source]¶

    pylorax.api.utils module¶

    API utility functions

    -
    +
    -pylorax.api.utils.blueprint_exists(api, branch, blueprint_name)[source]¶
    +pylorax.api.utils.blueprint_exists(api, branch, blueprint_name)[source]¶

    Return True if the blueprint exists

    Parameters
    @@ -3180,9 +3180,9 @@ If the commit has already been tagged it will return false.

    -
    +
    -pylorax.api.utils.take_limits(iterable, offset, limit)[source]¶
    +pylorax.api.utils.take_limits(iterable, offset, limit)[source]¶

    Apply offset and limit to an iterable object

    Parameters
    @@ -3230,9 +3230,9 @@ error response with it set to false and an error message included.

    used then the API will use the master branch for blueprints. If you want to create a new branch use the new or workspace routes with ?branch=<branch-name> to store the new blueprint on the new branch.

    -
    +
    -pylorax.api.v0.v0_blueprints_changes(blueprint_names)[source]¶
    +pylorax.api.v0.v0_blueprints_changes(blueprint_names)[source]¶

    Return the changes to a blueprint or list of blueprints

    /api/v0/blueprints/changes/<blueprint_names>[?offset=0&limit=20]

    @@ -3295,9 +3295,9 @@ hash can be passed to /api/v0/blueprints/diff/ to retrieve the exac
    -
    +
    -pylorax.api.v0.v0_blueprints_delete(blueprint_name)[source]¶
    +pylorax.api.v0.v0_blueprints_delete(blueprint_name)[source]¶

    Delete a blueprint from git

    DELETE /api/v0/blueprints/delete/<blueprint_name>

    @@ -3310,9 +3310,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_blueprints_delete_workspace(blueprint_name)[source]¶
    +pylorax.api.v0.v0_blueprints_delete_workspace(blueprint_name)[source]¶

    Delete a blueprint from the workspace

    DELETE /api/v0/blueprints/workspace/<blueprint_name>

    @@ -3324,9 +3324,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_blueprints_depsolve(blueprint_names)[source]¶
    +pylorax.api.v0.v0_blueprints_depsolve(blueprint_names)[source]¶

    Return the dependencies for a blueprint

    /api/v0/blueprints/depsolve/<blueprint_names>

    @@ -3404,9 +3404,9 @@ and packages in modules, and any error will be in errors
    -
    +
    -pylorax.api.v0.v0_blueprints_diff(blueprint_name, from_commit, to_commit)[source]¶
    +pylorax.api.v0.v0_blueprints_diff(blueprint_name, from_commit, to_commit)[source]¶

    Return the differences between two commits of a blueprint

    /api/v0/blueprints/diff/<blueprint_name>/<from_commit>/<to_commit>

    @@ -3453,9 +3453,9 @@ The contents for these will be the old/new values for them.

    -
    +
    -pylorax.api.v0.v0_blueprints_freeze(blueprint_names)[source]¶
    +pylorax.api.v0.v0_blueprints_freeze(blueprint_names)[source]¶

    Return the blueprint with the exact modules and packages selected by depsolve

    /api/v0/blueprints/freeze/<blueprint_names>

    @@ -3499,9 +3499,9 @@ to the exact versions chosen by depsolving the blueprint.

    -
    +
    -pylorax.api.v0.v0_blueprints_info(blueprint_names)[source]¶
    +pylorax.api.v0.v0_blueprints_info(blueprint_names)[source]¶

    Return the contents of the blueprint, or a list of blueprints

    /api/v0/blueprints/info/<blueprint_names>[?format=<json|toml>]

    @@ -3565,7 +3565,7 @@ errors will both be returned.

    -
    +
    pylorax.api.v0.v0_blueprints_list()[source]¶

    List the available blueprints on a branch.

    @@ -3587,7 +3587,7 @@ errors will both be returned.

    -
    +
    pylorax.api.v0.v0_blueprints_new()[source]¶

    Commit a new blueprint

    @@ -3601,9 +3601,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_blueprints_tag(blueprint_name)[source]¶
    +pylorax.api.v0.v0_blueprints_tag(blueprint_name)[source]¶

    Tag a blueprint's latest blueprint commit as a 'revision'

    POST /api/v0/blueprints/tag/<blueprint_name>

    @@ -3616,9 +3616,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_blueprints_undo(blueprint_name, commit)[source]¶
    +pylorax.api.v0.v0_blueprints_undo(blueprint_name, commit)[source]¶

    Undo changes to a blueprint by reverting to a previous commit.

    POST /api/v0/blueprints/undo/<blueprint_name>/<commit>

    @@ -3629,7 +3629,7 @@ error response with it set to false and an error message included.

    -
    +
    pylorax.api.v0.v0_blueprints_workspace()[source]¶

    Write a blueprint to the workspace

    @@ -3645,9 +3645,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_compose_cancel(uuid)[source]¶
    +pylorax.api.v0.v0_compose_cancel(uuid)[source]¶

    Cancel a running compose and delete its results directory

    DELETE /api/v0/compose/cancel/<uuid>

    @@ -3663,9 +3663,9 @@ status of True if it is successful.

    -
    +
    -pylorax.api.v0.v0_compose_delete(uuids)[source]¶
    +pylorax.api.v0.v0_compose_delete(uuids)[source]¶

    Delete the compose results for the listed uuids

    DELETE /api/v0/compose/delete/<uuids>

    @@ -3685,7 +3685,7 @@ status of True if it is successful.

    -
    +
    pylorax.api.v0.v0_compose_failed()[source]¶

    Return the list of failed composes

    @@ -3711,7 +3711,7 @@ status of True if it is successful.

    -
    +
    pylorax.api.v0.v0_compose_finished()[source]¶

    Return the list of finished composes

    @@ -3746,9 +3746,9 @@ status of True if it is successful.

    -
    +
    -pylorax.api.v0.v0_compose_image(uuid)[source]¶
    +pylorax.api.v0.v0_compose_image(uuid)[source]¶

    Return the output image for the build

    /api/v0/compose/image/<uuid>

    @@ -3757,9 +3757,9 @@ from the build with the UUID as a prefix. eg. UUID-root.tar.xz or UUID-boot.iso.
    -
    +
    -pylorax.api.v0.v0_compose_info(uuid)[source]¶
    +pylorax.api.v0.v0_compose_info(uuid)[source]¶

    Return detailed info about a compose

    /api/v0/compose/info/<uuid>

    @@ -3811,9 +3811,9 @@ contain the following information:

    -
    +
    -pylorax.api.v0.v0_compose_log_tail(uuid)[source]¶
    +pylorax.api.v0.v0_compose_log_tail(uuid)[source]¶

    Return the tail of the most currently relevant log

    /api/v0/compose/log/<uuid>[?size=KiB]

    @@ -3843,9 +3843,9 @@ line boundary.

    -
    +
    -pylorax.api.v0.v0_compose_logs(uuid)[source]¶
    +pylorax.api.v0.v0_compose_logs(uuid)[source]¶

    Return a tar of the metadata for the build

    /api/v0/compose/logs/<uuid>

    @@ -3856,9 +3856,9 @@ UUID-logs.tar

    -
    +
    -pylorax.api.v0.v0_compose_metadata(uuid)[source]¶
    +pylorax.api.v0.v0_compose_metadata(uuid)[source]¶

    Return a tar of the metadata for the build

    /api/v0/compose/metadata/<uuid>

    @@ -3871,7 +3871,7 @@ UUID-metadata.tar

    -
    +
    pylorax.api.v0.v0_compose_queue()[source]¶

    Return the status of the new and running queues

    @@ -3913,9 +3913,9 @@ and the build that is running.

    -
    +
    -pylorax.api.v0.v0_compose_results(uuid)[source]¶
    +pylorax.api.v0.v0_compose_results(uuid)[source]¶

    Return a tar of the metadata and the results for the build

    /api/v0/compose/results/<uuid>

    @@ -3928,7 +3928,7 @@ UUID.tar

    -
    +
    pylorax.api.v0.v0_compose_start()[source]¶

    Start a compose

    @@ -3963,9 +3963,9 @@ build and add it to the queue. It returns the build uuid and a status if it succ
    -
    +
    -pylorax.api.v0.v0_compose_status(uuids)[source]¶
    +pylorax.api.v0.v0_compose_status(uuids)[source]¶

    Return the status of the listed uuids

    /api/v0/compose/status/<uuids>[?blueprint=<blueprint_name>&status=<compose_status>&type=<compose_type>]

    @@ -3999,7 +3999,7 @@ details for all composes.

    -
    +
    pylorax.api.v0.v0_compose_types()[source]¶

    Return the list of enabled output types

    @@ -4021,9 +4021,9 @@ details for all composes.

    -
    +
    -pylorax.api.v0.v0_modules_info(module_names)[source]¶
    +pylorax.api.v0.v0_modules_info(module_names)[source]¶

    Return detailed information about the listed modules

    /api/v0/modules/info/<module_names>

    @@ -4062,9 +4062,9 @@ details for all composes.

    -
    +
    -pylorax.api.v0.v0_modules_list(module_names=None)[source]¶
    +pylorax.api.v0.v0_modules_list(module_names=None)[source]¶

    List available modules, filtering by module_names

    /api/v0/modules/list[?offset=0&limit=20]

    @@ -4119,9 +4119,9 @@ arguments.

    -
    +
    -pylorax.api.v0.v0_projects_depsolve(project_names)[source]¶
    +pylorax.api.v0.v0_projects_depsolve(project_names)[source]¶

    Return detailed information about the listed projects

    /api/v0/projects/depsolve/<project_names>

    @@ -4159,9 +4159,9 @@ to satisfy the request.

    -
    +
    -pylorax.api.v0.v0_projects_info(project_names)[source]¶
    +pylorax.api.v0.v0_projects_info(project_names)[source]¶

    Return detailed information about the listed projects

    /api/v0/projects/info/<project_names>

    @@ -4202,7 +4202,7 @@ of the package along with the list of available builds.

    -
    +
    pylorax.api.v0.v0_projects_list()[source]¶

    List all of the available projects/packages

    @@ -4231,9 +4231,9 @@ but this can be changed by setting the offset and limit
    -
    +
    -pylorax.api.v0.v0_projects_source_delete(source_name)[source]¶
    +pylorax.api.v0.v0_projects_source_delete(source_name)[source]¶

    Delete the named source and return a status response

    DELETE /api/v0/projects/source/delete/<source-name>

    @@ -4244,9 +4244,9 @@ error response with it set to false and an error message included.

    -
    +
    -pylorax.api.v0.v0_projects_source_info(source_names)[source]¶
    +pylorax.api.v0.v0_projects_source_info(source_names)[source]¶

    Return detailed info about the list of sources

    /api/v0/projects/source/info/<source-names>

    @@ -4277,7 +4277,7 @@ will have it set to false. System sources cannot be changed or deleted.

    -
    +
    pylorax.api.v0.v0_projects_source_list()[source]¶

    Return the list of source names

    @@ -4298,7 +4298,7 @@ will have it set to false. System sources cannot be changed or deleted.

    -
    +
    pylorax.api.v0.v0_projects_source_new()[source]¶

    Add a new package source. Or change an existing one

    @@ -4339,7 +4339,7 @@ of the new version of the source. It will overwrite the previous one.

    pylorax.api.v1 module¶

    Setup v1 of the API server

    -
    +
    pylorax.api.v1.v1_compose_failed()[source]¶

    Return the list of failed composes

    @@ -4385,7 +4385,7 @@ of the new version of the source. It will overwrite the previous one.

    -
    +
    pylorax.api.v1.v1_compose_finished()[source]¶

    Return the list of finished composes

    @@ -4440,9 +4440,9 @@ of the new version of the source. It will overwrite the previous one.

    -
    +
    -pylorax.api.v1.v1_compose_info(uuid)[source]¶
    +pylorax.api.v1.v1_compose_info(uuid)[source]¶

    Return detailed info about a compose

    /api/v1/compose/info/<uuid>

    @@ -4514,7 +4514,7 @@ contain the following information:

    -
    +
    pylorax.api.v1.v1_compose_queue()[source]¶

    Return the status of the new and running queues

    @@ -4576,7 +4576,7 @@ and the build that is running.

    -
    +
    pylorax.api.v1.v1_compose_start()[source]¶

    Start a compose

    @@ -4644,9 +4644,9 @@ finishes.

    -
    +
    -pylorax.api.v1.v1_compose_status(uuids)[source]¶
    +pylorax.api.v1.v1_compose_status(uuids)[source]¶

    Return the status of the listed uuids

    /api/v1/compose/status/<uuids>[?blueprint=<blueprint_name>&status=<compose_status>&type=<compose_type>]

    @@ -4700,9 +4700,9 @@ details for all composes.

    -
    +
    -pylorax.api.v1.v1_compose_uploads_delete(upload_uuid)[source]¶
    +pylorax.api.v1.v1_compose_uploads_delete(upload_uuid)[source]¶

    Delete an upload and disassociate it from its compose

    DELETE /api/v1/upload/delete/<upload_uuid>

    @@ -4716,9 +4716,9 @@ details for all composes.

    -
    +
    -pylorax.api.v1.v1_compose_uploads_schedule(compose_uuid)[source]¶
    +pylorax.api.v1.v1_compose_uploads_schedule(compose_uuid)[source]¶

    Schedule an upload of a compose to a given cloud provider

    POST /api/v1/uploads/schedule/<compose_uuid>

    @@ -4759,9 +4759,9 @@ details for all composes.

    -
    +
    -pylorax.api.v1.v1_projects_source_info(source_ids)[source]¶
    +pylorax.api.v1.v1_projects_source_info(source_ids)[source]¶

    Return detailed info about the list of sources

    /api/v1/projects/source/info/<source-ids>

    @@ -4795,7 +4795,7 @@ will have it set to false. System sources cannot be changed or deleted.

    to id and name is now used for the longer descriptive name of the repository.

    -
    +
    pylorax.api.v1.v1_projects_source_new()[source]¶

    Add a new package source. Or change an existing one

    @@ -4834,9 +4834,9 @@ of the new version of the source. It will overwrite the previous one.

    to id and name is now used for the longer descriptive name of the repository.

    -
    +
    -pylorax.api.v1.v1_providers_delete(provider_name, profile)[source]¶
    +pylorax.api.v1.v1_providers_delete(provider_name, profile)[source]¶

    Delete a provider's profile settings

    DELETE /api/v1/upload/providers/delete/<provider_name>/<profile>

    @@ -4849,7 +4849,7 @@ to id
    -
    +
    pylorax.api.v1.v1_providers_save()[source]¶

    Save provider settings as a profile for later use

    @@ -4882,9 +4882,9 @@ to id
    -
    +
    -pylorax.api.v1.v1_upload_cancel(upload_uuid)[source]¶
    +pylorax.api.v1.v1_upload_cancel(upload_uuid)[source]¶

    Cancel an upload that is either queued or in progress

    DELETE /api/v1/upload/cancel/<upload_uuid>

    @@ -4898,9 +4898,9 @@ to id
    -
    +
    -pylorax.api.v1.v1_upload_info(upload_uuid)[source]¶
    +pylorax.api.v1.v1_upload_info(upload_uuid)[source]¶

    Returns information about a given upload

    GET /api/v1/upload/info/<upload_uuid>

    @@ -4931,9 +4931,9 @@ to id
    -
    +
    -pylorax.api.v1.v1_upload_log(upload_uuid)[source]¶
    +pylorax.api.v1.v1_upload_log(upload_uuid)[source]¶

    Returns an upload's log

    GET /api/v1/upload/log/<upload_uuid>

    @@ -4948,7 +4948,7 @@ to id
    -
    +
    pylorax.api.v1.v1_upload_providers()[source]¶

    Return the information about all upload providers, including their @@ -4986,9 +4986,9 @@ display names, expected settings, and saved profiles. Refer to the

    -
    +
    -pylorax.api.v1.v1_upload_reset(upload_uuid)[source]¶
    +pylorax.api.v1.v1_upload_reset(upload_uuid)[source]¶

    Reset an upload so it can be attempted again

    POST /api/v1/upload/reset/<upload_uuid>

    @@ -5022,9 +5022,9 @@ display names, expected settings, and saved profiles. Refer to the

    pylorax.api.workspace module¶

    -
    +
    -pylorax.api.workspace.workspace_delete(repo, branch, recipe_name)[source]¶
    +pylorax.api.workspace.workspace_delete(repo, branch, recipe_name)[source]¶

    Delete the recipe from the workspace

    Parameters
    @@ -5043,9 +5043,9 @@ display names, expected settings, and saved profiles. Refer to the
    -
    +
    -pylorax.api.workspace.workspace_dir(repo, branch)[source]¶
    +pylorax.api.workspace.workspace_dir(repo, branch)[source]¶

    Create the workspace's path from a Repository and branch

    Parameters
    @@ -5063,9 +5063,51 @@ display names, expected settings, and saved profiles. Refer to the
    -
    +
    +
    +pylorax.api.workspace.workspace_exists(repo, branch, recipe_name)[source]¶
    +

    Return true of the workspace recipe exists

    +
    +
    Parameters
    +
      +
    • repo (Git.Repository) -- Open repository

    • +
    • branch (str) -- Branch name

    • +
    • recipe_name (str) -- The name of the recipe

    • +
    +
    +
    Returns
    +

    True if the file exists

    +
    +
    Return type
    +

    bool

    +
    +
    +
    + +
    +
    +pylorax.api.workspace.workspace_filename(repo, branch, recipe_name)[source]¶
    +

    Return the path and filename of the workspace recipe

    +
    +
    Parameters
    +
      +
    • repo (Git.Repository) -- Open repository

    • +
    • branch (str) -- Branch name

    • +
    • recipe_name (str) -- The name of the recipe

    • +
    +
    +
    Returns
    +

    workspace recipe path and filename

    +
    +
    Return type
    +

    str

    +
    +
    +
    + +
    -pylorax.api.workspace.workspace_read(repo, branch, recipe_name)[source]¶
    +pylorax.api.workspace.workspace_read(repo, branch, recipe_name)[source]¶

    Read a Recipe from the branch's workspace

    Parameters
    @@ -5087,9 +5129,9 @@ display names, expected settings, and saved profiles. Refer to the
    -
    +
    -pylorax.api.workspace.workspace_write(repo, branch, recipe)[source]¶
    +pylorax.api.workspace.workspace_write(repo, branch, recipe)[source]¶

    Write a recipe to the workspace

    Parameters
    diff --git a/docs/html/pylorax.html b/docs/html/pylorax.html index ab86dbe0..4ac4ef7c 100644 --- a/docs/html/pylorax.html +++ b/docs/html/pylorax.html @@ -8,7 +8,7 @@ - pylorax package — Lorax 33.2 documentation + pylorax package — Lorax 33.10 documentation @@ -21,10 +21,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    @@ -237,42 +237,42 @@

    pylorax.base module¶

    -
    +
    class pylorax.base.BaseLoraxClass[source]¶

    Bases: object

    -
    +
    -pcritical(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)[source]¶
    +pcritical(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
    -
    +
    -pdebug(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)[source]¶
    +pdebug(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
    -
    +
    -perror(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)[source]¶
    +perror(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
    -
    +
    -pinfo(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)[source]¶
    +pinfo(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
    -
    +
    -pwarning(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>)[source]¶
    +pwarning(msg, fobj=<_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>)[source]¶
    -
    +
    -class pylorax.base.DataHolder(**kwargs)[source]¶
    +class pylorax.base.DataHolder(**kwargs)[source]¶

    Bases: dict

    -
    +
    copy() → a shallow copy of D[source]¶
    @@ -282,13 +282,13 @@

    pylorax.buildstamp module¶

    -
    +
    -class pylorax.buildstamp.BuildStamp(product, version, bugurl, isfinal, buildarch, variant='')[source]¶
    +class pylorax.buildstamp.BuildStamp(product, version, bugurl, isfinal, buildarch, variant='')[source]¶

    Bases: object

    -
    +
    -write(outfile)[source]¶
    +write(outfile)[source]¶
    @@ -296,39 +296,39 @@

    pylorax.cmdline module¶

    -
    +
    -pylorax.cmdline.lmc_parser(dracut_default='')[source]¶
    +pylorax.cmdline.lmc_parser(dracut_default='')[source]¶

    Return a ArgumentParser object for live-media-creator.

    -
    +
    -pylorax.cmdline.lorax_parser(dracut_default='')[source]¶
    +pylorax.cmdline.lorax_parser(dracut_default='')[source]¶

    Return the ArgumentParser for lorax

    pylorax.creator module¶

    -
    +
    -class pylorax.creator.FakeDNF(conf)[source]¶
    +class pylorax.creator.FakeDNF(conf)[source]¶

    Bases: object

    A minimal DNF object suitable for passing to RuntimeBuilder

    lmc uses RuntimeBuilder to run the arch specific iso creation templates, so the the installroot config value is the important part of this. Everything else should be a nop.

    -
    +
    reset()[source]¶
    -
    +
    -pylorax.creator.calculate_disk_size(opts, ks)[source]¶
    +pylorax.creator.calculate_disk_size(opts, ks)[source]¶

    Calculate the disk size from the kickstart

    Parameters
    @@ -347,9 +347,9 @@ this. Everything else should be a nop.

    Also takes into account the use of reqpart or reqpart --add-boot

    -
    +
    -pylorax.creator.check_kickstart(ks, opts)[source]¶
    +pylorax.creator.check_kickstart(ks, opts)[source]¶

    Check the parsed kickstart object for errors

    Parameters
    @@ -367,9 +367,9 @@ this. Everything else should be a nop.

    -
    +
    -pylorax.creator.create_pxe_config(template, images_dir, live_image_name, add_args=None)[source]¶
    +pylorax.creator.create_pxe_config(template, images_dir, live_image_name, add_args=None)[source]¶

    Create template for pxe to live configuration

    Parameters
    @@ -382,17 +382,17 @@ this. Everything else should be a nop.

    -
    +
    -pylorax.creator.dracut_args(opts)[source]¶
    +pylorax.creator.dracut_args(opts)[source]¶

    Return a list of the args to pass to dracut

    Return the default argument list unless one of the dracut cmdline arguments has been used.

    -
    +
    -pylorax.creator.find_ostree_root(phys_root)[source]¶
    +pylorax.creator.find_ostree_root(phys_root)[source]¶

    Find root of ostree deployment

    Parameters
    @@ -410,9 +410,9 @@ has been used.

    -
    +
    -pylorax.creator.get_arch(mount_dir)[source]¶
    +pylorax.creator.get_arch(mount_dir)[source]¶

    Get the kernel arch

    Returns
    @@ -424,9 +424,9 @@ has been used.

    -
    +
    -pylorax.creator.is_image_mounted(disk_img)[source]¶
    +pylorax.creator.is_image_mounted(disk_img)[source]¶

    Check to see if the disk_img is mounted

    Returns
    @@ -438,9 +438,9 @@ has been used.

    -
    +
    -pylorax.creator.make_appliance(disk_img, name, template, outfile, networks=None, ram=1024, vcpus=1, arch=None, title='Linux', project='Linux', releasever='32')[source]¶
    +pylorax.creator.make_appliance(disk_img, name, template, outfile, networks=None, ram=1024, vcpus=1, arch=None, title='Linux', project='Linux', releasever='32')[source]¶

    Generate an appliance description file

    Parameters
    @@ -461,9 +461,9 @@ has been used.

    -
    +
    -pylorax.creator.make_image(opts, ks, cancel_func=None)[source]¶
    +pylorax.creator.make_image(opts, ks, cancel_func=None)[source]¶

    Install to a disk image

    Parameters
    @@ -483,9 +483,9 @@ has been used.

    Use qemu+boot.iso or anaconda to install to a disk image.

    -
    +
    -pylorax.creator.make_live_images(opts, work_dir, disk_img)[source]¶
    +pylorax.creator.make_live_images(opts, work_dir, disk_img)[source]¶

    Create live images from direcory or rootfs image

    Parameters
    @@ -507,9 +507,9 @@ out any deleted blocks to make it compress better. If this fails for any reason it will return None and log the error.

    -
    +
    -pylorax.creator.make_livecd(opts, mount_dir, work_dir)[source]¶
    +pylorax.creator.make_livecd(opts, mount_dir, work_dir)[source]¶

    Take the content from the disk image and make a livecd out of it

    Parameters
    @@ -531,9 +531,9 @@ root=live:CDLABEL=<volid> rd.live.image

    -
    +
    -pylorax.creator.make_runtime(opts, mount_dir, work_dir, size=None)[source]¶
    +pylorax.creator.make_runtime(opts, mount_dir, work_dir, size=None)[source]¶

    Make the squashfs image from a directory

    Parameters
    @@ -544,21 +544,27 @@ root=live:CDLABEL=<volid> rd.live.image

  • size (int) -- Size of disk image, in GiB

  • +
    Returns
    +

    rc of squashfs creation

    +
    +
    Return type
    +

    int

    +
    -
    +
    -pylorax.creator.mount_boot_part_over_root(img_mount)[source]¶
    +pylorax.creator.mount_boot_part_over_root(img_mount)[source]¶

    Mount boot partition to /boot of root fs mounted in img_mount

    Used for OSTree so it finds deployment configurations on live rootfs

    param img_mount: object with mounted disk image root partition type img_mount: imgutils.PartitionMount

    -
    +
    -pylorax.creator.rebuild_initrds_for_live(opts, sys_root_dir, results_dir)[source]¶
    +pylorax.creator.rebuild_initrds_for_live(opts, sys_root_dir, results_dir)[source]¶

    Rebuild intrds for pxe live image (root=live:http://)

    Parameters
    @@ -571,9 +577,9 @@ type img_mount: imgutils.PartitionMount

    -
    +
    -pylorax.creator.run_creator(opts, cancel_func=None)[source]¶
    +pylorax.creator.run_creator(opts, cancel_func=None)[source]¶

    Run the image creator process

    Parameters
    @@ -594,9 +600,9 @@ See the cmdline --help for livemedia-creator for the possible options

    (Yes, this is not ideal, but we can fix that later)

    -
    +
    -pylorax.creator.squashfs_args(opts)[source]¶
    +pylorax.creator.squashfs_args(opts)[source]¶

    Returns the compression type and args to use when making squashfs

    Parameters
    @@ -614,21 +620,21 @@ See the cmdline --help for livemedia-creator for the possible options

    pylorax.decorators module¶

    -
    +
    -pylorax.decorators.singleton(cls)[source]¶
    +pylorax.decorators.singleton(cls)[source]¶

    pylorax.discinfo module¶

    -
    +
    -class pylorax.discinfo.DiscInfo(release, basearch)[source]¶
    +class pylorax.discinfo.DiscInfo(release, basearch)[source]¶

    Bases: object

    -
    +
    -write(outfile)[source]¶
    +write(outfile)[source]¶
    @@ -636,9 +642,9 @@ See the cmdline --help for livemedia-creator for the possible options

    pylorax.dnfbase module¶

    -
    +
    -pylorax.dnfbase.get_dnf_base_object(installroot, sources, mirrorlists=None, repos=None, enablerepos=None, disablerepos=None, tempdir='/var/tmp', proxy=None, releasever='32', cachedir=None, logdir=None, sslverify=True, dnfplugins=None)[source]¶
    +pylorax.dnfbase.get_dnf_base_object(installroot, sources, mirrorlists=None, repos=None, enablerepos=None, disablerepos=None, tempdir='/var/tmp', proxy=None, releasever='32', cachedir=None, logdir=None, sslverify=True, dnfplugins=None)[source]¶

    Create a dnf Base object and setup the repositories and installroot

    Parameters
    @@ -663,39 +669,39 @@ If cachedir is None a dnf.cache directory is created inside tmpdir

    pylorax.dnfhelper module¶

    -
    +
    class pylorax.dnfhelper.LoraxDownloadCallback[source]¶

    Bases: DownloadProgress

    -
    +
    -end(payload, status, msg)[source]¶
    +end(payload, status, msg)[source]¶
    -
    +
    -progress(payload, done)[source]¶
    +progress(payload, done)[source]¶
    -
    +
    -start(total_files, total_size, total_drpms=0)[source]¶
    +start(total_files, total_size, total_drpms=0)[source]¶
    -
    +
    class pylorax.dnfhelper.LoraxRpmCallback[source]¶

    Bases: TransactionProgress

    -
    +
    -error(message)[source]¶
    +error(message)[source]¶
    -
    +
    -progress(package, action, ti_done, ti_total, ts_done, ts_total)[source]¶
    +progress(package, action, ti_done, ti_total, ts_done, ts_total)[source]¶
    @@ -703,18 +709,18 @@ If cachedir is None a dnf.cache directory is created inside tmpdir

    pylorax.executils module¶

    -
    +
    -class pylorax.executils.ExecProduct(rc, stdout, stderr)[source]¶
    +class pylorax.executils.ExecProduct(rc, stdout, stderr)[source]¶

    Bases: object

    -
    +
    pylorax.executils.augmentEnv()[source]¶
    -
    +
    pylorax.executils.execReadlines(command, argv, stdin=None, root='/', env_prune=None, filter_stderr=False, callback=<function <lambda>>, env_add=None, reset_handlers=True, reset_lang=True)[source]¶

    Execute an external command and return the line output of the command @@ -750,9 +756,9 @@ stdout and then keeps on truckin' there will be problems.

    This returns an iterator with the lines from the command until it has finished

    -
    +
    -pylorax.executils.execWithCapture(command, argv, stdin=None, root='/', log_output=True, filter_stderr=False, raise_err=False, callback=None, env_add=None, reset_handlers=True, reset_lang=True)[source]¶
    +pylorax.executils.execWithCapture(command, argv, stdin=None, root='/', log_output=True, filter_stderr=False, raise_err=False, callback=None, env_add=None, reset_handlers=True, reset_lang=True)[source]¶

    Run an external program and capture standard out and err.

    Parameters
    @@ -775,9 +781,9 @@ This returns an iterator with the lines from the command until it has finished
    -
    +
    -pylorax.executils.execWithRedirect(command, argv, stdin=None, stdout=None, root='/', env_prune=None, log_output=True, binary_output=False, raise_err=False, callback=None, env_add=None, reset_handlers=True, reset_lang=True)[source]¶
    +pylorax.executils.execWithRedirect(command, argv, stdin=None, stdout=None, root='/', env_prune=None, log_output=True, binary_output=False, raise_err=False, callback=None, env_add=None, reset_handlers=True, reset_lang=True)[source]¶

    Run an external program and redirect the output to a file.

    Parameters
    @@ -803,21 +809,21 @@ This returns an iterator with the lines from the command until it has finished
    -
    +
    -pylorax.executils.runcmd(cmd, **kwargs)[source]¶
    +pylorax.executils.runcmd(cmd, **kwargs)[source]¶

    run execWithRedirect with raise_err=True

    -
    +
    -pylorax.executils.runcmd_output(cmd, **kwargs)[source]¶
    +pylorax.executils.runcmd_output(cmd, **kwargs)[source]¶

    run execWithCapture with raise_err=True

    -
    +
    -pylorax.executils.setenv(name, value)[source]¶
    +pylorax.executils.setenv(name, value)[source]¶

    Set an environment variable to be used by child processes.

    This method does not modify os.environ for the running process, which is not thread-safe. If setenv has already been called for a particular @@ -832,9 +838,9 @@ variable name, the old value is overwritten.

    -
    +
    -pylorax.executils.startProgram(argv, root='/', stdin=None, stdout=-1, stderr=-2, env_prune=None, env_add=None, reset_handlers=True, reset_lang=True, **kwargs)[source]¶
    +pylorax.executils.startProgram(argv, root='/', stdin=None, stdout=- 1, stderr=- 2, env_prune=None, env_add=None, reset_handlers=True, reset_lang=True, **kwargs)[source]¶

    Start an external program and return the Popen object.

    The root and reset_handlers arguments are handled by passing a preexec_fn argument to subprocess.Popen, but an additional preexec_fn @@ -865,52 +871,52 @@ last.

    pylorax.imgutils module¶

    -
    +
    -class pylorax.imgutils.DMDev(dev, size, name=None)[source]¶
    +class pylorax.imgutils.DMDev(dev, size, name=None)[source]¶

    Bases: object

    -
    +
    -class pylorax.imgutils.LoopDev(filename, size=None)[source]¶
    +class pylorax.imgutils.LoopDev(filename, size=None)[source]¶

    Bases: object

    -
    +
    -class pylorax.imgutils.Mount(dev, opts='', mnt=None)[source]¶
    +class pylorax.imgutils.Mount(dev, opts='', mnt=None)[source]¶

    Bases: object

    -
    +
    -class pylorax.imgutils.PartitionMount(disk_img, mount_ok=None, submount=None)[source]¶
    +class pylorax.imgutils.PartitionMount(disk_img, mount_ok=None, submount=None)[source]¶

    Bases: object

    Mount a partitioned image file using kpartx

    -
    +
    -pylorax.imgutils.compress(command, root, outfile, compression='xz', compressargs=None)[source]¶
    +pylorax.imgutils.compress(command, root, outfile, compression='xz', compressargs=None)[source]¶

    Make a compressed archive of the given rootdir or file. command is a list of the archiver commands to run compression should be "xz", "gzip", "lzma", "bzip2", or None. compressargs will be used on the compression commandline.

    -
    +
    -pylorax.imgutils.copytree(src, dest, preserve=True)[source]¶
    +pylorax.imgutils.copytree(src, dest, preserve=True)[source]¶

    Copy a tree of files using cp -a, thus preserving modes, timestamps, links, acls, sparse files, xattrs, selinux contexts, etc. If preserve is False, uses cp -R (useful for modeless filesystems) raises CalledProcessError if copy fails.

    -
    +
    -pylorax.imgutils.default_image_name(compression, basename)[source]¶
    +pylorax.imgutils.default_image_name(compression, basename)[source]¶

    Return a default image name with the correct suffix for the compression type.

    Parameters
    @@ -926,43 +932,43 @@ raises CalledProcessError if copy fails.

    If the compression is unknown it defaults to xz

    -
    +
    -pylorax.imgutils.dm_attach(dev, size, name=None)[source]¶
    +pylorax.imgutils.dm_attach(dev, size, name=None)[source]¶

    Attach a devicemapper device to the given device, with the given size. If name is None, a random name will be chosen. Returns the device name. raises CalledProcessError if dmsetup fails.

    -
    +
    -pylorax.imgutils.dm_detach(dev)[source]¶
    +pylorax.imgutils.dm_detach(dev)[source]¶

    Detach the named devicemapper device. Returns False if dmsetup fails.

    -
    +
    -pylorax.imgutils.do_grafts(grafts, dest, preserve=True)[source]¶
    +pylorax.imgutils.do_grafts(grafts, dest, preserve=True)[source]¶

    Copy each of the items listed in grafts into dest. If the key ends with '/' it's assumed to be a directory which should be created, otherwise just the leading directories will be created.

    -
    +
    -pylorax.imgutils.estimate_size(rootdir, graft=None, fstype=None, blocksize=4096, overhead=256)[source]¶
    +pylorax.imgutils.estimate_size(rootdir, graft=None, fstype=None, blocksize=4096, overhead=256)[source]¶
    -
    +
    -pylorax.imgutils.get_loop_name(path)[source]¶
    +pylorax.imgutils.get_loop_name(path)[source]¶

    Return the loop device associated with the path. Raises RuntimeError if more than one loop is associated

    -
    +
    -pylorax.imgutils.kpartx_disk_img(disk_img)[source]¶
    +pylorax.imgutils.kpartx_disk_img(disk_img)[source]¶

    Attach a disk image's partitions to /dev/loopX using kpartx

    Parameters
    @@ -977,9 +983,9 @@ Raises RuntimeError if more than one loop is associated

    -
    +
    -pylorax.imgutils.loop_attach(outfile)[source]¶
    +pylorax.imgutils.loop_attach(outfile)[source]¶

    Attach a loop device to the given file. Return the loop device name.

    On rare occasions it appears that the device never shows up, some experiments seem to indicate that it may be a race with another process using /dev/loop* devices.

    @@ -987,15 +993,15 @@ seem to indicate that it may be a race with another process using /dev/loop* dev

    Raises CalledProcessError if losetup fails.

    -
    +
    -pylorax.imgutils.loop_detach(loopdev)[source]¶
    +pylorax.imgutils.loop_detach(loopdev)[source]¶

    Detach the given loop device. Return False on failure.

    -
    +
    -pylorax.imgutils.loop_waitfor(loop_dev, outfile)[source]¶
    +pylorax.imgutils.loop_waitfor(loop_dev, outfile)[source]¶

    Make sure the loop device is attached to the outfile.

    It seems that on rare occasions losetup can return before the /dev/loopX is ready for use, causing problems with mkfs. This tries to make sure that the @@ -1003,29 +1009,29 @@ loop device really is associated with the backing file before continuing.

    Raise RuntimeError if it isn't setup after 5 tries.

    -
    +
    -pylorax.imgutils.mkbtrfsimg(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    +pylorax.imgutils.mkbtrfsimg(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    -
    +
    -pylorax.imgutils.mkcpio(root, outfile, compression='xz', compressargs=None)[source]¶
    +pylorax.imgutils.mkcpio(root, outfile, compression='xz', compressargs=None)[source]¶
    -
    +
    -pylorax.imgutils.mkdosimg(rootdir, outfile, size=None, label='', mountargs='shortname=winnt, umask=0077', graft=None)[source]¶
    +pylorax.imgutils.mkdosimg(rootdir, outfile, size=None, label='', mountargs='shortname=winnt,umask=0077', graft=None)[source]¶
    -
    +
    -pylorax.imgutils.mkext4img(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    +pylorax.imgutils.mkext4img(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    -
    +
    -pylorax.imgutils.mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=None, mountargs='', graft=None)[source]¶
    +pylorax.imgutils.mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=None, mountargs='', graft=None)[source]¶

    Generic filesystem image creation function. fstype should be a filesystem type - "mkfs.${fstype}" must exist. graft should be a dict: {"some/path/in/image": "local/file/or/dir"}; @@ -1033,9 +1039,9 @@ if the path ends with a '/' it's assumed to be a directory. Will raise CalledProcessError if something goes wrong.

    -
    +
    -pylorax.imgutils.mkfsimage_from_disk(diskimage, fsimage, img_size=None, label='Anaconda')[source]¶
    +pylorax.imgutils.mkfsimage_from_disk(diskimage, fsimage, img_size=None, label='Anaconda')[source]¶

    Copy the / partition of a partitioned disk image to an un-partitioned disk image.

    @@ -1051,32 +1057,32 @@ it as small as possible

    -
    +
    -pylorax.imgutils.mkhfsimg(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    +pylorax.imgutils.mkhfsimg(rootdir, outfile, size=None, label='', mountargs='', graft=None)[source]¶
    -
    +
    -pylorax.imgutils.mkqcow2(outfile, size, options=None)[source]¶
    +pylorax.imgutils.mkqcow2(outfile, size, options=None)[source]¶

    use qemu-img to create a file of the given size. options is a list of options passed to qemu-img

    Default format is qcow2, override by passing "-f", fmt in options.

    -
    +
    -pylorax.imgutils.mkqemu_img(outfile, size, options=None)[source]¶
    +pylorax.imgutils.mkqemu_img(outfile, size, options=None)[source]¶

    use qemu-img to create a file of the given size. options is a list of options passed to qemu-img

    Default format is qcow2, override by passing "-f", fmt in options.

    -
    +
    -pylorax.imgutils.mkrootfsimg(rootdir, outfile, label, size=2, sysroot='')[source]¶
    +pylorax.imgutils.mkrootfsimg(rootdir, outfile, label, size=2, sysroot='')[source]¶

    Make rootfs image from a directory

    Parameters
    @@ -1091,26 +1097,26 @@ in options.

    -
    +
    -pylorax.imgutils.mksparse(outfile, size)[source]¶
    +pylorax.imgutils.mksparse(outfile, size)[source]¶

    use os.ftruncate to create a sparse file of the given size.

    -
    +
    -pylorax.imgutils.mksquashfs(rootdir, outfile, compression='default', compressargs=None)[source]¶
    +pylorax.imgutils.mksquashfs(rootdir, outfile, compression='default', compressargs=None)[source]¶

    Make a squashfs image containing the given rootdir.

    -
    +
    -pylorax.imgutils.mktar(root, outfile, compression='xz', compressargs=None, selinux=True)[source]¶
    +pylorax.imgutils.mktar(root, outfile, compression='xz', compressargs=None, selinux=True)[source]¶
    -
    +
    -pylorax.imgutils.mount(dev, opts='', mnt=None)[source]¶
    +pylorax.imgutils.mount(dev, opts='', mnt=None)[source]¶

    Mount the given device at the given mountpoint, using the given opts. opts should be a comma-separated string of mount options. if mnt is none, a temporary directory will be created and its path will be @@ -1118,15 +1124,15 @@ returned. raises CalledProcessError if mount fails.

    -
    +
    -pylorax.imgutils.round_to_blocks(size, blocksize)[source]¶
    +pylorax.imgutils.round_to_blocks(size, blocksize)[source]¶

    If size isn't a multiple of blocksize, round up to the next multiple

    -
    +
    -pylorax.imgutils.umount(mnt, lazy=False, maxretry=3, retrysleep=1.0, delete=True)[source]¶
    +pylorax.imgutils.umount(mnt, lazy=False, maxretry=3, retrysleep=1.0, delete=True)[source]¶

    Unmount the given mountpoint. If lazy is True, do a lazy umount (-l). If the mount was a temporary dir created by mount, it will be deleted. raises CalledProcessError if umount fails.

    @@ -1135,27 +1141,27 @@ raises CalledProcessError if umount fails.

    pylorax.installer module¶

    -
    +
    exception pylorax.installer.InstallError[source]¶

    Bases: Exception

    -
    +
    -class pylorax.installer.QEMUInstall(opts, iso, ks_paths, disk_img, img_size=2048, kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, cancel_func=None, virtio_host='127.0.0.1', virtio_port=6080, image_type=None, boot_uefi=False, ovmf_path=None)[source]¶
    +class pylorax.installer.QEMUInstall(opts, iso, ks_paths, disk_img, img_size=2048, kernel_args=None, memory=1024, vcpus=None, vnc=None, arch=None, cancel_func=None, virtio_host='127.0.0.1', virtio_port=6080, image_type=None, boot_uefi=False, ovmf_path=None)[source]¶

    Bases: object

    Run qemu using an iso and a kickstart

    -
    +
    QEMU_CMDS = {'aarch64': 'qemu-system-aarch64', 'arm': 'qemu-system-arm', 'i386': 'qemu-system-i386', 'ppc64le': 'qemu-system-ppc64', 'x86_64': 'qemu-system-x86_64'}¶
    -
    +
    -pylorax.installer.anaconda_cleanup(dirinstall_path)[source]¶
    +pylorax.installer.anaconda_cleanup(dirinstall_path)[source]¶

    Cleanup any leftover mounts from anaconda

    Parameters
    @@ -1172,9 +1178,9 @@ other mountpoints.

    Anaconda may also leave /run/anaconda.pid behind, clean that up as well.

    -
    +
    -pylorax.installer.append_initrd(initrd, files)[source]¶
    +pylorax.installer.append_initrd(initrd, files)[source]¶

    Append files to an initrd.

    Parameters
    @@ -1197,9 +1203,9 @@ copy of the initrd.

    cpio archive.

    -
    +
    -pylorax.installer.create_vagrant_metadata(path, size=0)[source]¶
    +pylorax.installer.create_vagrant_metadata(path, size=0)[source]¶

    Create a default Vagrant metadata.json file

    Parameters
    @@ -1211,9 +1217,9 @@ cpio archive.

    -
    +
    -pylorax.installer.find_free_port(start=5900, end=5999, host='127.0.0.1')[source]¶
    +pylorax.installer.find_free_port(start=5900, end=5999, host='127.0.0.1')[source]¶

    Return first free port in range.

    Parameters
    @@ -1232,9 +1238,9 @@ cpio archive.

    -
    +
    -pylorax.installer.novirt_cancel_check(cancel_funcs, proc)[source]¶
    +pylorax.installer.novirt_cancel_check(cancel_funcs, proc)[source]¶

    Check to see if there has been an error in the logs

    Parameters
    @@ -1251,9 +1257,9 @@ cpio archive.

    When an error is detected the process is terminated and this returns True

    -
    +
    -pylorax.installer.novirt_install(opts, disk_img, disk_size, cancel_func=None, tar_img=None)[source]¶
    +pylorax.installer.novirt_install(opts, disk_img, disk_size, cancel_func=None, tar_img=None)[source]¶

    Use Anaconda to install to a disk image

    Parameters
    @@ -1270,9 +1276,9 @@ When an error is detected the process is terminated and this returns True

    passed creates a qemu disk image or tarfile.

    -
    +
    -pylorax.installer.update_vagrant_metadata(path, size)[source]¶
    +pylorax.installer.update_vagrant_metadata(path, size)[source]¶

    Update the Vagrant metadata.json file

    Parameters
    @@ -1286,9 +1292,9 @@ passed creates a qemu disk image or tarfile.

    metadata file are set correctly. All other values are left untouched.

    -
    +
    -pylorax.installer.virt_install(opts, install_log, disk_img, disk_size, cancel_func=None, tar_img=None)[source]¶
    +pylorax.installer.virt_install(opts, install_log, disk_img, disk_size, cancel_func=None, tar_img=None)[source]¶

    Use qemu to install to a disk image

    Parameters
    @@ -1309,9 +1315,9 @@ image and then optionally, based on the opts passed, creates tarfile.

    pylorax.ltmpl module¶

    -
    +
    -class pylorax.ltmpl.LiveTemplateRunner(dbo, fatalerrors=True, templatedir=None, defaults=None)[source]¶
    +class pylorax.ltmpl.LiveTemplateRunner(dbo, fatalerrors=True, templatedir=None, defaults=None)[source]¶

    Bases: pylorax.ltmpl.TemplateRunner

    This class parses and executes a limited Lorax template. Sample usage:

    @@ -1321,9 +1327,9 @@ runner.run("live-install.tmpl")

    It is meant to be used with the live-install.tmpl which lists the per-arch pacages needed to build the live-iso output.

    -
    +
    -installpkg(*pkgs)[source]¶
    +installpkg(*pkgs)[source]¶
    installpkg [--required|--optional] [--except PKGGLOB [--except PKGGLOB ...]] PKGGLOB [PKGGLOB ...]

    Request installation of all packages matching the given globs. Note that this is just a request - nothing is actually installed @@ -1335,20 +1341,20 @@ until the 'run_pkg_transaction' command is given.

    -
    +
    -class pylorax.ltmpl.LoraxTemplate(directories=None)[source]¶
    +class pylorax.ltmpl.LoraxTemplate(directories=None)[source]¶

    Bases: object

    -
    +
    -parse(template_file, variables)[source]¶
    +parse(template_file, variables)[source]¶
    -
    +
    -class pylorax.ltmpl.LoraxTemplateRunner(inroot, outroot, dbo=None, fatalerrors=True, templatedir=None, defaults=None)[source]¶
    +class pylorax.ltmpl.LoraxTemplateRunner(inroot, outroot, dbo=None, fatalerrors=True, templatedir=None, defaults=None)[source]¶

    Bases: pylorax.ltmpl.TemplateRunner

    This class parses and executes Lorax templates. Sample usage:

    @@ -1375,9 +1381,9 @@ object - so adding a new command is as easy as adding a new function.

    on that line (after word splitting and brace expansion)

  • Commands should raise exceptions for errors - don't use sys.exit()

  • -
    +
    -append(filename, data)[source]¶
    +append(filename, data)[source]¶
    append FILE STRING

    Append STRING (followed by a newline character) to FILE. Python character escape sequences ('n', 't', etc.) will be @@ -1391,18 +1397,18 @@ append /etc/resolv.conf ""

    -
    +
    -chmod(fileglob, mode)[source]¶
    +chmod(fileglob, mode)[source]¶
    chmod FILEGLOB OCTALMODE

    Change the mode of all the files matching FILEGLOB to OCTALMODE.

    -
    +
    -copy(src, dest)[source]¶
    +copy(src, dest)[source]¶
    copy SRC DEST

    Copy SRC to DEST. If DEST is a directory, SRC will be copied inside it. @@ -1412,9 +1418,9 @@ that name, if the path leading to it exists.

    -
    +
    -createaddrsize(addr, src, dest)[source]¶
    +createaddrsize(addr, src, dest)[source]¶
    createaddrsize INITRD_ADDRESS INITRD ADDRSIZE

    Create the initrd.addrsize file required in LPAR boot process.

    @@ -1425,18 +1431,18 @@ that name, if the path leading to it exists.

    -
    +
    +hardlink(src, dest)[source]¶
    hardlink SRC DEST

    Create a hardlink at DEST which is linked to SRC.

    -
    +
    -install(srcglob, dest)[source]¶
    +install(srcglob, dest)[source]¶
    install SRC DEST

    Copy the given file (or files, if a glob is used) from the input tree to the given destination in the output tree. @@ -1454,9 +1460,9 @@ install /usr/share/myconfig/grub.conf.in /boot/grub.conf

    -
    +
    -installimg(*args)[source]¶
    +installimg(*args)[source]¶
    installimg [--xz|--gzip|--bzip2|--lzma] [-ARG|--ARG=OPTION] SRCDIR DESTFILE

    Create a compressed cpio archive of the contents of SRCDIR and place it in DESTFILE.

    @@ -1474,18 +1480,18 @@ passed to it. The default is xz -9

    -
    +
    -installinitrd(section, src, dest)[source]¶
    +installinitrd(section, src, dest)[source]¶
    installinitrd SECTION SRC DEST

    Same as installkernel, but for "initrd".

    -
    +
    -installkernel(section, src, dest)[source]¶
    +installkernel(section, src, dest)[source]¶
    installkernel SECTION SRC DEST

    Install the kernel from SRC in the input tree to DEST in the output tree, and then add an item to the treeinfo data store, in the named @@ -1499,9 +1505,9 @@ treeinfo SECTION kernel DEST

    -
    +
    -installpkg(*pkgs)[source]¶
    +installpkg(*pkgs)[source]¶
    installpkg [--required|--optional] [--except PKGGLOB [--except PKGGLOB ...]] PKGGLOB [PKGGLOB ...]

    Request installation of all packages matching the given globs. Note that this is just a request - nothing is actually installed @@ -1511,18 +1517,18 @@ until the 'run_pkg_transaction' command is given.

    -
    +
    -installupgradeinitrd(section, src, dest)[source]¶
    +installupgradeinitrd(section, src, dest)[source]¶
    installupgradeinitrd SECTION SRC DEST

    Same as installkernel, but for "upgrade".

    -
    +
    -log(msg)[source]¶
    +log(msg)[source]¶
    log MESSAGE

    Emit the given log message. Be sure to put it in quotes!

    @@ -1533,9 +1539,9 @@ until the 'run_pkg_transaction' command is given.

    -
    +
    -mkdir(*dirs)[source]¶
    +mkdir(*dirs)[source]¶
    mkdir DIR [DIR ...]

    Create the named DIR(s). Will create leading directories as needed.

    @@ -1546,18 +1552,18 @@ until the 'run_pkg_transaction' command is given.

    -
    +
    -move(src, dest)[source]¶
    +move(src, dest)[source]¶
    move SRC DEST

    Move SRC to DEST.

    -
    +
    -remove(*fileglobs)[source]¶
    +remove(*fileglobs)[source]¶
    remove FILEGLOB [FILEGLOB ...]

    Remove all the named files or directories. Will not raise exceptions if the file(s) are not found.

    @@ -1565,9 +1571,9 @@ Will not raise exceptions if the file(s) are not found.

    -
    +
    -removefrom(pkg, *globs)[source]¶
    +removefrom(pkg, *globs)[source]¶
    removefrom PKGGLOB [--allbut] FILEGLOB [FILEGLOB...]

    Remove all files matching the given file globs from the package (or packages) named. @@ -1582,9 +1588,9 @@ removefrom xfsprogs --allbut /sbin/*

    -
    +
    -removekmod(*globs)[source]¶
    +removekmod(*globs)[source]¶
    removekmod GLOB [GLOB...] [--allbut] KEEPGLOB [KEEPGLOB...]

    Remove all files and directories matching the given file globs from the kernel modules directory.

    @@ -1602,9 +1608,9 @@ removekmod drivers/char --allbut virtio_console hw_random

    -
    +
    -removepkg(*pkgs)[source]¶
    +removepkg(*pkgs)[source]¶
    removepkg PKGGLOB [PKGGLOB...]

    Delete the named package(s).

    @@ -1616,9 +1622,9 @@ Files are deleted, but directories are left behind.

    -
    +
    -replace(pat, repl, *fileglobs)[source]¶
    +replace(pat, repl, *fileglobs)[source]¶
    replace PATTERN REPLACEMENT FILEGLOB [FILEGLOB ...]

    Find-and-replace the given PATTERN (Python-style regex) with the given REPLACEMENT string for each of the files listed.

    @@ -1630,16 +1636,16 @@ REPLACEMENT string for each of the files listed.

    -
    +
    run_pkg_transaction()[source]¶

    Actually install all the packages requested by previous 'installpkg' commands.

    -
    +
    -runcmd(*cmdlist)[source]¶
    +runcmd(*cmdlist)[source]¶
    runcmd CMD [ARG ...]

    Run the given command with the given arguments.

    NOTE: All paths given MUST be COMPLETE, ABSOLUTE PATHS to the file @@ -1660,18 +1666,18 @@ remove ${f}

    -
    +
    +symlink(target, dest)[source]¶
    symlink SRC DEST

    Create a symlink at DEST which points to SRC.

    -
    +
    -systemctl(cmd, *units)[source]¶
    +systemctl(cmd, *units)[source]¶
    systemctl [enable|disable|mask] UNIT [UNIT...]

    Enable, disable, or mask the given systemd units.

    @@ -1683,9 +1689,9 @@ systemctl mask fedora-storage-init.service fedora-configure.service

    -
    +
    -treeinfo(section, key, *valuetoks)[source]¶
    +treeinfo(section, key, *valuetoks)[source]¶
    treeinfo SECTION KEY ARG [ARG ...]

    Add an item to the treeinfo data store. The given SECTION will have a new item added where @@ -1700,9 +1706,9 @@ KEY = ARG ARG ...

    -
    +
    -class pylorax.ltmpl.TemplateRunner(fatalerrors=True, templatedir=None, defaults=None, builtins=None)[source]¶
    +class pylorax.ltmpl.TemplateRunner(fatalerrors=True, templatedir=None, defaults=None, builtins=None)[source]¶

    Bases: object

    This class parses and executes Lorax templates. Sample usage:

    @@ -1727,44 +1733,44 @@ with the rest of the line as arguments

  • Parsing and execution are separate passes - so you can't use the result of a command in an %if statement (or any other control statements)!

  • -
    +
    -run(templatefile, **variables)[source]¶
    +run(templatefile, **variables)[source]¶
    -
    +
    -pylorax.ltmpl.brace_expand(s)[source]¶
    +pylorax.ltmpl.brace_expand(s)[source]¶
    -
    +
    -pylorax.ltmpl.rexists(pathname, root='')[source]¶
    +pylorax.ltmpl.rexists(pathname, root='')[source]¶
    -
    +
    -pylorax.ltmpl.rglob(pathname, root='/', fatal=False)[source]¶
    +pylorax.ltmpl.rglob(pathname, root='/', fatal=False)[source]¶
    -
    +
    -pylorax.ltmpl.split_and_expand(line)[source]¶
    +pylorax.ltmpl.split_and_expand(line)[source]¶

    pylorax.monitor module¶

    -
    +
    class pylorax.monitor.LogMonitor(log_path=None, host='localhost', port=0, timeout=None, log_request_handler_class=<class 'pylorax.monitor.LogRequestHandler'>)[source]¶

    Bases: object

    Setup a server to monitor the logs output by the installation

    This needs to be running before the virt-install runs, it expects there to be a listener on the port used for the virtio log port.

    -
    +
    shutdown()[source]¶

    Force shutdown of the monitoring thread

    @@ -1772,20 +1778,20 @@ there to be a listener on the port used for the virtio log port.

    -
    +
    -class pylorax.monitor.LogRequestHandler(request, client_address, server)[source]¶
    +class pylorax.monitor.LogRequestHandler(request, client_address, server)[source]¶

    Bases: socketserver.BaseRequestHandler

    Handle monitoring and saving the logfiles from the virtual install

    Incoming data is written to self.server.log_path and each line is checked for patterns that would indicate that the installation failed. self.server.log_error is set True when this happens.

    -
    +
    finish()[source]¶
    -
    +
    handle()[source]¶

    Write incoming data to a logfile and check for errors

    @@ -1794,9 +1800,9 @@ errors that indicate that the install failed.

    Loops until self.server.kill is True

    -
    +
    -iserror(line)[source]¶
    +iserror(line)[source]¶

    Check a line to see if it contains an error indicating installation failure

    Parameters
    @@ -1806,30 +1812,30 @@ errors that indicate that the install failed.

    If the line contains IGNORED it will be skipped.

    -
    +
    re_tests = ['packaging: base repo .* not valid', 'packaging: .* requires .*']¶
    -
    +
    setup()[source]¶

    Start writing to self.server.log_path

    -
    +
    simple_tests = ['Traceback (', 'traceback script(s) have been run', 'Out of memory:', 'Call Trace:', 'insufficient disk space:', 'Not enough disk space to download the packages', 'error populating transaction after', 'crashed on signal', 'packaging: Missed: NoSuchPackage', 'packaging: Installation failed', 'The following error occurred while installing. This is a fatal error']¶
    -
    +
    -class pylorax.monitor.LogServer(log_path, *args, **kwargs)[source]¶
    +class pylorax.monitor.LogServer(log_path, *args, **kwargs)[source]¶

    Bases: socketserver.TCPServer

    A TCP Server that listens for log data

    -
    +
    log_check()[source]¶

    Check to see if an error has been found in the log

    @@ -1843,7 +1849,7 @@ errors that indicate that the install failed.

    -
    +
    timeout = 60¶
    @@ -1853,22 +1859,22 @@ errors that indicate that the install failed.

    pylorax.mount module¶

    -
    +
    -class pylorax.mount.IsoMountpoint(iso_path, initrd_path=None)[source]¶
    +class pylorax.mount.IsoMountpoint(iso_path, initrd_path=None)[source]¶

    Bases: object

    Mount the iso and check to make sure the vmlinuz and initrd.img files exist

    Also check the iso for a a stage2 image and set a flag and extract the iso's label.

    stage2 can be either LiveOS/squashfs.img or images/install.img

    -
    +
    get_iso_label()[source]¶

    Get the iso's label using isoinfo

    Sets self.label if one is found

    -
    +
    umount()[source]¶

    Unmount the iso

    @@ -1882,125 +1888,125 @@ iso's label.

    pylorax.sysutils module¶

    -
    -
    -pylorax.sysutils.joinpaths(*args, **kwargs)[source]¶
    -
    - -
    -
    -pylorax.sysutils.touch(fname)[source]¶
    -
    - -
    -
    -pylorax.sysutils.replace(fname, find, sub)[source]¶
    -
    - -
    -
    -pylorax.sysutils.chown_(path, user=None, group=None, recursive=False)[source]¶
    -
    - -
    +
    -pylorax.sysutils.chmod_(path, mode, recursive=False)[source]¶
    +pylorax.sysutils.chmod_(path, mode, recursive=False)[source]¶
    -
    -
    -pylorax.sysutils.remove(target)[source]¶
    +
    +
    +pylorax.sysutils.chown_(path, user=None, group=None, recursive=False)[source]¶
    -
    +
    +
    +pylorax.sysutils.joinpaths(*args, **kwargs)[source]¶
    +
    + +
    -pylorax.sysutils.linktree(src, dst)[source]¶
    +pylorax.sysutils.linktree(src, dst)[source]¶ +
    + +
    +
    +pylorax.sysutils.remove(target)[source]¶
    +
    + +
    +
    +pylorax.sysutils.replace(fname, find, sub)[source]¶
    +
    + +
    +
    +pylorax.sysutils.touch(fname)[source]¶

    pylorax.treebuilder module¶

    -
    +
    -class pylorax.treebuilder.RuntimeBuilder(product, arch, dbo, templatedir=None, installpkgs=None, excludepkgs=None, add_templates=None, add_template_vars=None, skip_branding=False)[source]¶
    +class pylorax.treebuilder.RuntimeBuilder(product, arch, dbo, templatedir=None, installpkgs=None, excludepkgs=None, add_templates=None, add_template_vars=None, skip_branding=False)[source]¶

    Bases: object

    Builds the anaconda runtime image.

    -
    +
    cleanup()[source]¶

    Remove unneeded packages and files with runtime-cleanup.tmpl

    -
    +
    -create_ext4_runtime(outfile='/var/tmp/squashfs.img', compression='xz', compressargs=None, size=2)[source]¶
    +create_ext4_runtime(outfile='/var/tmp/squashfs.img', compression='xz', compressargs=None, size=2)[source]¶

    Create a squashfs compressed ext4 runtime

    -
    +
    -create_squashfs_runtime(outfile='/var/tmp/squashfs.img', compression='xz', compressargs=None, size=2)[source]¶
    +create_squashfs_runtime(outfile='/var/tmp/squashfs.img', compression='xz', compressargs=None, size=2)[source]¶

    Create a plain squashfs runtime

    -
    +
    finished()[source]¶

    Done using RuntimeBuilder

    Close the dnf base object

    -
    +
    generate_module_data()[source]¶
    -
    +
    install()[source]¶

    Install packages and do initial setup with runtime-install.tmpl

    -
    +
    postinstall()[source]¶

    Do some post-install setup work with runtime-postinstall.tmpl

    -
    +
    verify()[source]¶

    Ensure that contents of the installroot can run

    -
    +
    -writepkglists(pkglistdir)[source]¶
    +writepkglists(pkglistdir)[source]¶

    debugging data: write out lists of package contents

    -
    +
    -writepkgsizes(pkgsizefile)[source]¶
    +writepkgsizes(pkgsizefile)[source]¶

    debugging data: write a big list of pkg sizes

    -
    +
    -class pylorax.treebuilder.TreeBuilder(product, arch, inroot, outroot, runtime, isolabel, domacboot=True, doupgrade=True, templatedir=None, add_templates=None, add_template_vars=None, workdir=None, extra_boot_args='')[source]¶
    +class pylorax.treebuilder.TreeBuilder(product, arch, inroot, outroot, runtime, isolabel, domacboot=True, doupgrade=True, templatedir=None, add_templates=None, add_template_vars=None, workdir=None, extra_boot_args='')[source]¶

    Bases: object

    Builds the arch-specific boot images. inroot should be the installtree root (the newly-built runtime dir)

    -
    +
    build()[source]¶
    -
    +
    -copy_dracut_hooks(hooks)[source]¶
    +copy_dracut_hooks(hooks)[source]¶

    Copy the hook scripts in hooks into the installroot's /tmp/ and return a list of commands to pass to dracut when creating the initramfs

    @@ -2009,7 +2015,7 @@ target dracut hook directory (eg. [("99anaconda-copy-ks.sh", "/lib/dracut/hooks/pre-pivot")])

    -
    +
    property dracut_hooks_path¶

    Return the path to the lorax dracut hooks scripts

    @@ -2017,19 +2023,19 @@ target dracut hook directory otherwise default to /usr/share/lorax/dracut_hooks

    -
    +
    implantisomd5()[source]¶
    -
    +
    property kernels¶
    -
    +
    -rebuild_initrds(add_args=None, backup='', prefix='')[source]¶
    +rebuild_initrds(add_args=None, backup='', prefix='')[source]¶

    Rebuild all the initrds in the tree. If backup is specified, each initrd will be renamed with backup as a suffix before rebuilding. If backup is empty, the existing initrd files will be overwritten. @@ -2041,19 +2047,19 @@ name of the kernel.

    -
    +
    -pylorax.treebuilder.findkernels(root='/', kdir='boot')[source]¶
    +pylorax.treebuilder.findkernels(root='/', kdir='boot')[source]¶
    -
    +
    -pylorax.treebuilder.generate_module_info(moddir, outfile=None)[source]¶
    +pylorax.treebuilder.generate_module_info(moddir, outfile=None)[source]¶
    -
    +
    -pylorax.treebuilder.string_lower(string)[source]¶
    +pylorax.treebuilder.string_lower(string)[source]¶

    Return a lowercase string.

    Parameters
    @@ -2063,26 +2069,26 @@ name of the kernel.

    This is used as a filter in the templates.

    -
    +
    -pylorax.treebuilder.udev_escape(label)[source]¶
    +pylorax.treebuilder.udev_escape(label)[source]¶

    pylorax.treeinfo module¶

    -
    +
    -class pylorax.treeinfo.TreeInfo(product, version, variant, basearch, packagedir='')[source]¶
    +class pylorax.treeinfo.TreeInfo(product, version, variant, basearch, packagedir='')[source]¶

    Bases: object

    -
    +
    -add_section(section, data)[source]¶
    +add_section(section, data)[source]¶
    -
    +
    -write(outfile)[source]¶
    +write(outfile)[source]¶
    @@ -2090,47 +2096,47 @@ name of the kernel.

    Module contents¶

    -
    +
    -class pylorax.ArchData(buildarch)[source]¶
    +class pylorax.ArchData(buildarch)[source]¶

    Bases: pylorax.base.DataHolder

    -
    +
    bcj_arch = {'arm': 'arm', 'armhfp': 'arm', 'i386': 'x86', 'ppc64le': 'powerpc', 'x86_64': 'x86'}¶
    -
    +
    lib64_arches = ('x86_64', 'ppc64le', 's390x', 'ia64', 'aarch64')¶
    -
    +
    class pylorax.Lorax[source]¶

    Bases: pylorax.base.BaseLoraxClass

    -
    +
    -configure(conf_file='/etc/lorax/lorax.conf')[source]¶
    +configure(conf_file='/etc/lorax/lorax.conf')[source]¶
    -
    +
    -init_file_logging(logdir, logname='pylorax.log')[source]¶
    +init_file_logging(logdir, logname='pylorax.log')[source]¶
    -
    +
    init_stream_logging()[source]¶
    -
    +
    -run(dbo, product, version, release, variant='', bugurl='', isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, domacboot=True, doupgrade=True, remove_temp=False, installpkgs=None, excludepkgs=None, size=2, add_templates=None, add_template_vars=None, add_arch_templates=None, add_arch_template_vars=None, verify=True, user_dracut_args=None, squashfs_only=False, skip_branding=False)[source]¶
    +run(dbo, product, version, release, variant='', bugurl='', isfinal=False, workdir=None, outputdir=None, buildarch=None, volid=None, domacboot=True, doupgrade=True, remove_temp=False, installpkgs=None, excludepkgs=None, size=2, add_templates=None, add_template_vars=None, add_arch_templates=None, add_arch_template_vars=None, verify=True, user_dracut_args=None, squashfs_only=False, skip_branding=False)[source]¶
    -
    +
    property templatedir¶

    Find the template directory.

    @@ -2140,9 +2146,9 @@ Otherwise use the sharedir

    -
    +
    -pylorax.find_templates(templatedir='/usr/share/lorax')[source]¶
    +pylorax.find_templates(templatedir='/usr/share/lorax')[source]¶

    Find the templates to use.

    Parameters
    @@ -2160,20 +2166,20 @@ lowest numbered directory entry is returned.

    eg. /usr/share/lorax/templates.d/99-generic/

    -
    +
    -pylorax.get_buildarch(dbo)[source]¶
    +pylorax.get_buildarch(dbo)[source]¶
    -
    +
    pylorax.log_selinux_state()[source]¶

    Log the current state of selinux

    -
    +
    -pylorax.setup_logging(logfile, theLogger)[source]¶
    +pylorax.setup_logging(logfile, theLogger)[source]¶

    Setup the various logs

    Parameters
    diff --git a/docs/html/search.html b/docs/html/search.html index 25c5103b..dc635445 100644 --- a/docs/html/search.html +++ b/docs/html/search.html @@ -8,7 +8,7 @@ - Search — Lorax 33.2 documentation + Search — Lorax 33.10 documentation @@ -22,10 +22,10 @@ - - - - + + + + @@ -60,7 +60,7 @@
    - 33.2 + 33.10
    diff --git a/docs/html/searchindex.js b/docs/html/searchindex.js index 731c5163..4bc79b9b 100644 --- a/docs/html/searchindex.js +++ b/docs/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({docnames:["composer","composer-cli","composer.cli","index","intro","lifted","livemedia-creator","lorax","lorax-composer","mkksiso","modules","product-images","pylorax","pylorax.api"],envversion:{"sphinx.domains.c":1,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":1,"sphinx.domains.javascript":1,"sphinx.domains.math":2,"sphinx.domains.python":1,"sphinx.domains.rst":1,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":1,"sphinx.ext.viewcode":1,sphinx:56},filenames:["composer.rst","composer-cli.rst","composer.cli.rst","index.rst","intro.rst","lifted.rst","livemedia-creator.rst","lorax.rst","lorax-composer.rst","mkksiso.rst","modules.rst","product-images.rst","pylorax.rst","pylorax.api.rst"],objects:{"":{composer:[0,0,0,"-"],lifted:[5,0,0,"-"],pylorax:[12,0,0,"-"]},"composer.cli":{blueprints:[2,0,0,"-"],cmdline:[2,0,0,"-"],compose:[2,0,0,"-"],help:[2,0,0,"-"],main:[2,1,1,""],modules:[2,0,0,"-"],projects:[2,0,0,"-"],providers:[2,0,0,"-"],sources:[2,0,0,"-"],status:[2,0,0,"-"],upload:[2,0,0,"-"],utilities:[2,0,0,"-"]},"composer.cli.blueprints":{blueprints_changes:[2,1,1,""],blueprints_cmd:[2,1,1,""],blueprints_delete:[2,1,1,""],blueprints_depsolve:[2,1,1,""],blueprints_diff:[2,1,1,""],blueprints_freeze:[2,1,1,""],blueprints_freeze_save:[2,1,1,""],blueprints_freeze_show:[2,1,1,""],blueprints_list:[2,1,1,""],blueprints_push:[2,1,1,""],blueprints_save:[2,1,1,""],blueprints_show:[2,1,1,""],blueprints_tag:[2,1,1,""],blueprints_undo:[2,1,1,""],blueprints_workspace:[2,1,1,""],dict_names:[2,1,1,""],prettyCommitDetails:[2,1,1,""],pretty_dict:[2,1,1,""],pretty_diff_entry:[2,1,1,""]},"composer.cli.cmdline":{composer_cli_parser:[2,1,1,""]},"composer.cli.compose":{compose_cancel:[2,1,1,""],compose_cmd:[2,1,1,""],compose_delete:[2,1,1,""],compose_image:[2,1,1,""],compose_info:[2,1,1,""],compose_list:[2,1,1,""],compose_log:[2,1,1,""],compose_logs:[2,1,1,""],compose_metadata:[2,1,1,""],compose_results:[2,1,1,""],compose_start:[2,1,1,""],compose_status:[2,1,1,""],compose_types:[2,1,1,""]},"composer.cli.modules":{modules_cmd:[2,1,1,""]},"composer.cli.projects":{projects_cmd:[2,1,1,""],projects_info:[2,1,1,""],projects_list:[2,1,1,""]},"composer.cli.providers":{providers_cmd:[2,1,1,""],providers_delete:[2,1,1,""],providers_info:[2,1,1,""],providers_list:[2,1,1,""],providers_push:[2,1,1,""],providers_save:[2,1,1,""],providers_show:[2,1,1,""],providers_template:[2,1,1,""]},"composer.cli.sources":{sources_add:[2,1,1,""],sources_cmd:[2,1,1,""],sources_delete:[2,1,1,""],sources_info:[2,1,1,""],sources_list:[2,1,1,""]},"composer.cli.status":{status_cmd:[2,1,1,""]},"composer.cli.upload":{upload_cancel:[2,1,1,""],upload_cmd:[2,1,1,""],upload_delete:[2,1,1,""],upload_info:[2,1,1,""],upload_list:[2,1,1,""],upload_log:[2,1,1,""],upload_reset:[2,1,1,""],upload_start:[2,1,1,""]},"composer.cli.utilities":{argify:[2,1,1,""],frozen_toml_filename:[2,1,1,""],handle_api_result:[2,1,1,""],packageNEVRA:[2,1,1,""],toml_filename:[2,1,1,""]},"composer.http_client":{api_url:[0,1,1,""],append_query:[0,1,1,""],delete_url_json:[0,1,1,""],download_file:[0,1,1,""],get_filename:[0,1,1,""],get_url_json:[0,1,1,""],get_url_json_unlimited:[0,1,1,""],get_url_raw:[0,1,1,""],post_url:[0,1,1,""],post_url_json:[0,1,1,""],post_url_toml:[0,1,1,""]},"composer.unix_socket":{UnixHTTPConnection:[0,2,1,""],UnixHTTPConnectionPool:[0,2,1,""]},"composer.unix_socket.UnixHTTPConnection":{connect:[0,3,1,""]},"lifted.config":{configure:[5,1,1,""]},"lifted.providers":{delete_profile:[5,1,1,""],list_providers:[5,1,1,""],load_profiles:[5,1,1,""],load_settings:[5,1,1,""],resolve_playbook_path:[5,1,1,""],resolve_provider:[5,1,1,""],save_settings:[5,1,1,""],validate_settings:[5,1,1,""]},"lifted.queue":{cancel_upload:[5,1,1,""],create_upload:[5,1,1,""],delete_upload:[5,1,1,""],get_all_uploads:[5,1,1,""],get_upload:[5,1,1,""],get_uploads:[5,1,1,""],ready_upload:[5,1,1,""],reset_upload:[5,1,1,""],start_upload_monitor:[5,1,1,""]},"lifted.upload":{Upload:[5,2,1,""]},"lifted.upload.Upload":{cancel:[5,3,1,""],execute:[5,3,1,""],is_cancellable:[5,3,1,""],ready:[5,3,1,""],reset:[5,3,1,""],serializable:[5,3,1,""],set_status:[5,3,1,""],summary:[5,3,1,""]},"pylorax.ArchData":{bcj_arch:[12,4,1,""],lib64_arches:[12,4,1,""]},"pylorax.Lorax":{configure:[12,3,1,""],init_file_logging:[12,3,1,""],init_stream_logging:[12,3,1,""],run:[12,3,1,""],templatedir:[12,3,1,""]},"pylorax.api":{bisect:[13,0,0,"-"],checkparams:[13,0,0,"-"],cmdline:[13,0,0,"-"],compose:[13,0,0,"-"],config:[13,0,0,"-"],dnfbase:[13,0,0,"-"],errors:[13,0,0,"-"],flask_blueprint:[13,0,0,"-"],gitrpm:[13,0,0,"-"],projects:[13,0,0,"-"],queue:[13,0,0,"-"],recipes:[13,0,0,"-"],regexes:[13,0,0,"-"],server:[13,0,0,"-"],timestamp:[13,0,0,"-"],toml:[13,0,0,"-"],utils:[13,0,0,"-"],v0:[13,0,0,"-"],v1:[13,0,0,"-"],workspace:[13,0,0,"-"]},"pylorax.api.bisect":{insort_left:[13,1,1,""]},"pylorax.api.checkparams":{checkparams:[13,1,1,""]},"pylorax.api.cmdline":{lorax_composer_parser:[13,1,1,""]},"pylorax.api.compose":{add_customizations:[13,1,1,""],bootloader_append:[13,1,1,""],compose_args:[13,1,1,""],compose_types:[13,1,1,""],customize_ks_template:[13,1,1,""],firewall_cmd:[13,1,1,""],get_default_services:[13,1,1,""],get_extra_pkgs:[13,1,1,""],get_firewall_settings:[13,1,1,""],get_kernel_append:[13,1,1,""],get_keyboard_layout:[13,1,1,""],get_languages:[13,1,1,""],get_services:[13,1,1,""],get_timezone_settings:[13,1,1,""],keyboard_cmd:[13,1,1,""],lang_cmd:[13,1,1,""],move_compose_results:[13,1,1,""],repo_to_ks:[13,1,1,""],services_cmd:[13,1,1,""],start_build:[13,1,1,""],test_templates:[13,1,1,""],timezone_cmd:[13,1,1,""],write_ks_group:[13,1,1,""],write_ks_root:[13,1,1,""],write_ks_user:[13,1,1,""]},"pylorax.api.config":{ComposerConfig:[13,2,1,""],configure:[13,1,1,""],make_dnf_dirs:[13,1,1,""],make_owned_dir:[13,1,1,""],make_queue_dirs:[13,1,1,""]},"pylorax.api.config.ComposerConfig":{get_default:[13,3,1,""]},"pylorax.api.dnfbase":{DNFLock:[13,2,1,""],get_base_object:[13,1,1,""]},"pylorax.api.dnfbase.DNFLock":{lock:[13,3,1,""],lock_check:[13,3,1,""]},"pylorax.api.flask_blueprint":{BlueprintSetupStateSkip:[13,2,1,""],BlueprintSkip:[13,2,1,""]},"pylorax.api.flask_blueprint.BlueprintSetupStateSkip":{add_url_rule:[13,3,1,""]},"pylorax.api.flask_blueprint.BlueprintSkip":{make_setup_state:[13,3,1,""]},"pylorax.api.gitrpm":{GitArchiveTarball:[13,2,1,""],GitRpmBuild:[13,2,1,""],create_gitrpm_repo:[13,1,1,""],get_repo_description:[13,1,1,""],make_git_rpm:[13,1,1,""]},"pylorax.api.gitrpm.GitArchiveTarball":{write_file:[13,3,1,""]},"pylorax.api.gitrpm.GitRpmBuild":{add_git_tarball:[13,3,1,""],check:[13,3,1,""],clean:[13,3,1,""],cleanup_tmpdir:[13,3,1,""],get_base_dir:[13,3,1,""]},"pylorax.api.projects":{ProjectsError:[13,5,1,""],api_changelog:[13,1,1,""],api_time:[13,1,1,""],delete_repo_source:[13,1,1,""],dep_evra:[13,1,1,""],dep_nevra:[13,1,1,""],dnf_repo_to_file_repo:[13,1,1,""],estimate_size:[13,1,1,""],get_repo_sources:[13,1,1,""],get_source_ids:[13,1,1,""],modules_info:[13,1,1,""],modules_list:[13,1,1,""],new_repo_source:[13,1,1,""],pkg_to_build:[13,1,1,""],pkg_to_dep:[13,1,1,""],pkg_to_project:[13,1,1,""],pkg_to_project_info:[13,1,1,""],proj_to_module:[13,1,1,""],projects_depsolve:[13,1,1,""],projects_depsolve_with_size:[13,1,1,""],projects_info:[13,1,1,""],projects_list:[13,1,1,""],repo_to_source:[13,1,1,""],source_to_repo:[13,1,1,""],source_to_repodict:[13,1,1,""]},"pylorax.api.queue":{build_status:[13,1,1,""],check_queues:[13,1,1,""],compose_detail:[13,1,1,""],get_compose_type:[13,1,1,""],get_image_name:[13,1,1,""],make_compose:[13,1,1,""],monitor:[13,1,1,""],queue_status:[13,1,1,""],start_queue_monitor:[13,1,1,""],uuid_add_upload:[13,1,1,""],uuid_cancel:[13,1,1,""],uuid_delete:[13,1,1,""],uuid_get_uploads:[13,1,1,""],uuid_image:[13,1,1,""],uuid_info:[13,1,1,""],uuid_log:[13,1,1,""],uuid_ready_upload:[13,1,1,""],uuid_remove_upload:[13,1,1,""],uuid_schedule_upload:[13,1,1,""],uuid_status:[13,1,1,""],uuid_tar:[13,1,1,""]},"pylorax.api.recipes":{CommitDetails:[13,2,1,""],CommitTimeValError:[13,5,1,""],NewRecipeGit:[13,1,1,""],Recipe:[13,2,1,""],RecipeError:[13,5,1,""],RecipeFileError:[13,5,1,""],RecipeGit:[13,2,1,""],RecipeGroup:[13,2,1,""],RecipeModule:[13,2,1,""],RecipePackage:[13,2,1,""],check_list_case:[13,1,1,""],check_recipe_dict:[13,1,1,""],check_required_list:[13,1,1,""],commit_recipe:[13,1,1,""],commit_recipe_directory:[13,1,1,""],commit_recipe_file:[13,1,1,""],customizations_diff:[13,1,1,""],delete_file:[13,1,1,""],delete_recipe:[13,1,1,""],diff_lists:[13,1,1,""],find_commit_tag:[13,1,1,""],find_field_value:[13,1,1,""],find_name:[13,1,1,""],find_recipe_obj:[13,1,1,""],get_commit_details:[13,1,1,""],get_revision_from_tag:[13,1,1,""],gfile:[13,1,1,""],head_commit:[13,1,1,""],is_commit_tag:[13,1,1,""],is_parent_diff:[13,1,1,""],list_branch_files:[13,1,1,""],list_commit_files:[13,1,1,""],list_commits:[13,1,1,""],open_or_create_repo:[13,1,1,""],prepare_commit:[13,1,1,""],read_commit:[13,1,1,""],read_commit_spec:[13,1,1,""],read_recipe_and_id:[13,1,1,""],read_recipe_commit:[13,1,1,""],recipe_diff:[13,1,1,""],recipe_filename:[13,1,1,""],recipe_from_dict:[13,1,1,""],recipe_from_file:[13,1,1,""],recipe_from_toml:[13,1,1,""],repo_file_exists:[13,1,1,""],revert_file:[13,1,1,""],revert_recipe:[13,1,1,""],tag_file_commit:[13,1,1,""],tag_recipe_commit:[13,1,1,""],write_commit:[13,1,1,""]},"pylorax.api.recipes.Recipe":{bump_version:[13,3,1,""],filename:[13,3,1,""],freeze:[13,3,1,""],group_names:[13,3,1,""],module_names:[13,3,1,""],module_nver:[13,3,1,""],package_names:[13,3,1,""],package_nver:[13,3,1,""],toml:[13,3,1,""]},"pylorax.api.server":{GitLock:[13,2,1,""]},"pylorax.api.server.GitLock":{dir:[13,3,1,""],lock:[13,3,1,""],repo:[13,3,1,""]},"pylorax.api.timestamp":{timestamp_dict:[13,1,1,""],write_timestamp:[13,1,1,""]},"pylorax.api.toml":{TomlError:[13,5,1,""],dump:[13,1,1,""],dumps:[13,1,1,""],load:[13,1,1,""],loads:[13,1,1,""]},"pylorax.api.utils":{blueprint_exists:[13,1,1,""],take_limits:[13,1,1,""]},"pylorax.api.v0":{v0_blueprints_changes:[13,1,1,""],v0_blueprints_delete:[13,1,1,""],v0_blueprints_delete_workspace:[13,1,1,""],v0_blueprints_depsolve:[13,1,1,""],v0_blueprints_diff:[13,1,1,""],v0_blueprints_freeze:[13,1,1,""],v0_blueprints_info:[13,1,1,""],v0_blueprints_list:[13,1,1,""],v0_blueprints_new:[13,1,1,""],v0_blueprints_tag:[13,1,1,""],v0_blueprints_undo:[13,1,1,""],v0_blueprints_workspace:[13,1,1,""],v0_compose_cancel:[13,1,1,""],v0_compose_delete:[13,1,1,""],v0_compose_failed:[13,1,1,""],v0_compose_finished:[13,1,1,""],v0_compose_image:[13,1,1,""],v0_compose_info:[13,1,1,""],v0_compose_log_tail:[13,1,1,""],v0_compose_logs:[13,1,1,""],v0_compose_metadata:[13,1,1,""],v0_compose_queue:[13,1,1,""],v0_compose_results:[13,1,1,""],v0_compose_start:[13,1,1,""],v0_compose_status:[13,1,1,""],v0_compose_types:[13,1,1,""],v0_modules_info:[13,1,1,""],v0_modules_list:[13,1,1,""],v0_projects_depsolve:[13,1,1,""],v0_projects_info:[13,1,1,""],v0_projects_list:[13,1,1,""],v0_projects_source_delete:[13,1,1,""],v0_projects_source_info:[13,1,1,""],v0_projects_source_list:[13,1,1,""],v0_projects_source_new:[13,1,1,""]},"pylorax.api.v1":{v1_compose_failed:[13,1,1,""],v1_compose_finished:[13,1,1,""],v1_compose_info:[13,1,1,""],v1_compose_queue:[13,1,1,""],v1_compose_start:[13,1,1,""],v1_compose_status:[13,1,1,""],v1_compose_uploads_delete:[13,1,1,""],v1_compose_uploads_schedule:[13,1,1,""],v1_projects_source_info:[13,1,1,""],v1_projects_source_new:[13,1,1,""],v1_providers_delete:[13,1,1,""],v1_providers_save:[13,1,1,""],v1_upload_cancel:[13,1,1,""],v1_upload_info:[13,1,1,""],v1_upload_log:[13,1,1,""],v1_upload_providers:[13,1,1,""],v1_upload_reset:[13,1,1,""]},"pylorax.api.workspace":{workspace_delete:[13,1,1,""],workspace_dir:[13,1,1,""],workspace_read:[13,1,1,""],workspace_write:[13,1,1,""]},"pylorax.base":{BaseLoraxClass:[12,2,1,""],DataHolder:[12,2,1,""]},"pylorax.base.BaseLoraxClass":{pcritical:[12,3,1,""],pdebug:[12,3,1,""],perror:[12,3,1,""],pinfo:[12,3,1,""],pwarning:[12,3,1,""]},"pylorax.base.DataHolder":{copy:[12,3,1,""]},"pylorax.buildstamp":{BuildStamp:[12,2,1,""]},"pylorax.buildstamp.BuildStamp":{write:[12,3,1,""]},"pylorax.cmdline":{lmc_parser:[12,1,1,""],lorax_parser:[12,1,1,""]},"pylorax.creator":{FakeDNF:[12,2,1,""],calculate_disk_size:[12,1,1,""],check_kickstart:[12,1,1,""],create_pxe_config:[12,1,1,""],dracut_args:[12,1,1,""],find_ostree_root:[12,1,1,""],get_arch:[12,1,1,""],is_image_mounted:[12,1,1,""],make_appliance:[12,1,1,""],make_image:[12,1,1,""],make_live_images:[12,1,1,""],make_livecd:[12,1,1,""],make_runtime:[12,1,1,""],mount_boot_part_over_root:[12,1,1,""],rebuild_initrds_for_live:[12,1,1,""],run_creator:[12,1,1,""],squashfs_args:[12,1,1,""]},"pylorax.creator.FakeDNF":{reset:[12,3,1,""]},"pylorax.decorators":{singleton:[12,1,1,""]},"pylorax.discinfo":{DiscInfo:[12,2,1,""]},"pylorax.discinfo.DiscInfo":{write:[12,3,1,""]},"pylorax.dnfbase":{get_dnf_base_object:[12,1,1,""]},"pylorax.dnfhelper":{LoraxDownloadCallback:[12,2,1,""],LoraxRpmCallback:[12,2,1,""]},"pylorax.dnfhelper.LoraxDownloadCallback":{end:[12,3,1,""],progress:[12,3,1,""],start:[12,3,1,""]},"pylorax.dnfhelper.LoraxRpmCallback":{error:[12,3,1,""],progress:[12,3,1,""]},"pylorax.executils":{ExecProduct:[12,2,1,""],augmentEnv:[12,1,1,""],execReadlines:[12,1,1,""],execWithCapture:[12,1,1,""],execWithRedirect:[12,1,1,""],runcmd:[12,1,1,""],runcmd_output:[12,1,1,""],setenv:[12,1,1,""],startProgram:[12,1,1,""]},"pylorax.imgutils":{DMDev:[12,2,1,""],LoopDev:[12,2,1,""],Mount:[12,2,1,""],PartitionMount:[12,2,1,""],compress:[12,1,1,""],copytree:[12,1,1,""],default_image_name:[12,1,1,""],dm_attach:[12,1,1,""],dm_detach:[12,1,1,""],do_grafts:[12,1,1,""],estimate_size:[12,1,1,""],get_loop_name:[12,1,1,""],kpartx_disk_img:[12,1,1,""],loop_attach:[12,1,1,""],loop_detach:[12,1,1,""],loop_waitfor:[12,1,1,""],mkbtrfsimg:[12,1,1,""],mkcpio:[12,1,1,""],mkdosimg:[12,1,1,""],mkext4img:[12,1,1,""],mkfsimage:[12,1,1,""],mkfsimage_from_disk:[12,1,1,""],mkhfsimg:[12,1,1,""],mkqcow2:[12,1,1,""],mkqemu_img:[12,1,1,""],mkrootfsimg:[12,1,1,""],mksparse:[12,1,1,""],mksquashfs:[12,1,1,""],mktar:[12,1,1,""],mount:[12,1,1,""],round_to_blocks:[12,1,1,""],umount:[12,1,1,""]},"pylorax.installer":{InstallError:[12,5,1,""],QEMUInstall:[12,2,1,""],anaconda_cleanup:[12,1,1,""],append_initrd:[12,1,1,""],create_vagrant_metadata:[12,1,1,""],find_free_port:[12,1,1,""],novirt_cancel_check:[12,1,1,""],novirt_install:[12,1,1,""],update_vagrant_metadata:[12,1,1,""],virt_install:[12,1,1,""]},"pylorax.installer.QEMUInstall":{QEMU_CMDS:[12,4,1,""]},"pylorax.ltmpl":{LiveTemplateRunner:[12,2,1,""],LoraxTemplate:[12,2,1,""],LoraxTemplateRunner:[12,2,1,""],TemplateRunner:[12,2,1,""],brace_expand:[12,1,1,""],rexists:[12,1,1,""],rglob:[12,1,1,""],split_and_expand:[12,1,1,""]},"pylorax.ltmpl.LiveTemplateRunner":{installpkg:[12,3,1,""]},"pylorax.ltmpl.LoraxTemplate":{parse:[12,3,1,""]},"pylorax.ltmpl.LoraxTemplateRunner":{append:[12,3,1,""],chmod:[12,3,1,""],copy:[12,3,1,""],createaddrsize:[12,3,1,""],hardlink:[12,3,1,""],install:[12,3,1,""],installimg:[12,3,1,""],installinitrd:[12,3,1,""],installkernel:[12,3,1,""],installpkg:[12,3,1,""],installupgradeinitrd:[12,3,1,""],log:[12,3,1,""],mkdir:[12,3,1,""],move:[12,3,1,""],remove:[12,3,1,""],removefrom:[12,3,1,""],removekmod:[12,3,1,""],removepkg:[12,3,1,""],replace:[12,3,1,""],run_pkg_transaction:[12,3,1,""],runcmd:[12,3,1,""],symlink:[12,3,1,""],systemctl:[12,3,1,""],treeinfo:[12,3,1,""]},"pylorax.ltmpl.TemplateRunner":{run:[12,3,1,""]},"pylorax.monitor":{LogMonitor:[12,2,1,""],LogRequestHandler:[12,2,1,""],LogServer:[12,2,1,""]},"pylorax.monitor.LogMonitor":{shutdown:[12,3,1,""]},"pylorax.monitor.LogRequestHandler":{finish:[12,3,1,""],handle:[12,3,1,""],iserror:[12,3,1,""],re_tests:[12,4,1,""],setup:[12,3,1,""],simple_tests:[12,4,1,""]},"pylorax.monitor.LogServer":{log_check:[12,3,1,""],timeout:[12,4,1,""]},"pylorax.mount":{IsoMountpoint:[12,2,1,""]},"pylorax.mount.IsoMountpoint":{get_iso_label:[12,3,1,""],umount:[12,3,1,""]},"pylorax.sysutils":{chmod_:[12,1,1,""],chown_:[12,1,1,""],joinpaths:[12,1,1,""],linktree:[12,1,1,""],remove:[12,1,1,""],replace:[12,1,1,""],touch:[12,1,1,""]},"pylorax.treebuilder":{RuntimeBuilder:[12,2,1,""],TreeBuilder:[12,2,1,""],findkernels:[12,1,1,""],generate_module_info:[12,1,1,""],string_lower:[12,1,1,""],udev_escape:[12,1,1,""]},"pylorax.treebuilder.RuntimeBuilder":{cleanup:[12,3,1,""],create_ext4_runtime:[12,3,1,""],create_squashfs_runtime:[12,3,1,""],finished:[12,3,1,""],generate_module_data:[12,3,1,""],install:[12,3,1,""],postinstall:[12,3,1,""],verify:[12,3,1,""],writepkglists:[12,3,1,""],writepkgsizes:[12,3,1,""]},"pylorax.treebuilder.TreeBuilder":{build:[12,3,1,""],copy_dracut_hooks:[12,3,1,""],dracut_hooks_path:[12,3,1,""],implantisomd5:[12,3,1,""],kernels:[12,3,1,""],rebuild_initrds:[12,3,1,""]},"pylorax.treeinfo":{TreeInfo:[12,2,1,""]},"pylorax.treeinfo.TreeInfo":{add_section:[12,3,1,""],write:[12,3,1,""]},composer:{cli:[2,0,0,"-"],http_client:[0,0,0,"-"],unix_socket:[0,0,0,"-"]},lifted:{config:[5,0,0,"-"],providers:[5,0,0,"-"],queue:[5,0,0,"-"],upload:[5,0,0,"-"]},pylorax:{ArchData:[12,2,1,""],Lorax:[12,2,1,""],api:[13,0,0,"-"],base:[12,0,0,"-"],buildstamp:[12,0,0,"-"],cmdline:[12,0,0,"-"],creator:[12,0,0,"-"],decorators:[12,0,0,"-"],discinfo:[12,0,0,"-"],dnfbase:[12,0,0,"-"],dnfhelper:[12,0,0,"-"],executils:[12,0,0,"-"],find_templates:[12,1,1,""],get_buildarch:[12,1,1,""],imgutils:[12,0,0,"-"],installer:[12,0,0,"-"],log_selinux_state:[12,1,1,""],ltmpl:[12,0,0,"-"],monitor:[12,0,0,"-"],mount:[12,0,0,"-"],output:[12,0,0,"-"],setup_logging:[12,1,1,""],sysutils:[12,0,0,"-"],treebuilder:[12,0,0,"-"],treeinfo:[12,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","method","Python method"],"4":["py","attribute","Python attribute"],"5":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:method","4":"py:attribute","5":"py:exception"},terms:{"01t08":13,"03374adbf080fe34f5c6c29f2e49cc2b86958bf2":13,"03397f8d":13,"037a3d56":13,"06e8":13,"08t00":13,"0ad":13,"0e08ecbb708675bfabc82952599a1712a843779d":13,"0fa2":13,"0instal":13,"10t23":13,"11t00":13,"11t01":13,"13z":13,"14526ba628bb":13,"18bb14679fc7":13,"1kb":2,"21898dfd":13,"23t00":13,"28z":13,"29b492f26ed35d80800b536623bafc51e2f0eff2":13,"2b4174b3614b":13,"2ping":13,"30z":13,"3700mib":12,"3726a1093fd0":13,"397f":13,"3e11eb87a63d289662cba4b1804a0947a6843379":13,"3rn8evie2t50lmvybyihtgvrhcaecmeck31l":8,"41ef9c3e4b73":13,"42fc":13,"43e9":13,"44c0":13,"45502a6d":13,"45e380f39894":13,"47z":13,"48a5":13,"48ec":13,"4a23":13,"4af9":13,"4b70":13,"4b8a":13,"4c68":13,"4c9f":13,"4cdb":13,"4e22":13,"523b":13,"52z":13,"56z":13,"572eb0d0":13,"61b799739ce8":13,"6c8d38e3b211":13,"6d292bd0":13,"7078e521a54b12eae31c3fd028680da7a0815a4d":13,"70b84195":13,"745712b2":13,"7f12d0129e65":13,"7f16":13,"870f":13,"8c8435ef":13,"8d7d":13,"96db":13,"99anaconda":12,"9ac9":13,"9bf1":13,"9c81":13,"9d26":13,"9d9d":13,"boolean":5,"byte":13,"case":[8,13],"catch":[6,12],"char":12,"class":[0,5,11,12,13],"default":[1,5,8,9,12,13],"final":[1,4,6,7,8,11,12,13],"function":[2,5,8,12,13],"import":[6,12,13],"int":[2,12,13],"long":1,"new":[0,1,2,4,5,6,7,8,9,12],"null":[6,13],"public":[6,8],"return":[0,1,2,5,8,12,13],"short":[8,13],"switch":6,"true":[0,2,5,6,7,8,12,13],"try":[1,6,12,13],"var":[5,6,7,8,12,13],"while":[8,11,12,13],ADDING:12,Adding:12,And:6,But:[6,8],For:[0,1,6,8,12,13],Its:[4,7],NOT:13,Not:12,One:[6,8],RTS:13,THE:13,The:[0,1,2,4,5,6,8,9,11,12,13],Then:9,There:[6,8,9,12,13],These:[6,7,8,11,13],Use:[6,7,12,13],Used:[6,12,13],Uses:13,Using:[7,13],Will:12,Yes:12,__dict__:5,__init__:0,_io:12,_map:8,a215:13,a2ef832e6b1a:13,a697ca405cdf:13,a8ef:13,aarch64:[7,11,12],abbrevi:6,abl:[7,8,9],abort:6,about:[1,2,5,6,13],abov:[1,6],absolut:12,accept:8,access:[1,6,8,13],accomplish:6,account:[8,12],acff:13,acl:[12,13],action:12,activ:[6,8],actual:[12,13],ad52:13,add2636e7459:13,add:[0,1,2,5,6,7,9,11,12,13],add_arch_templ:[7,12],add_arch_template_var:[7,12],add_arg:12,add_custom:13,add_git_tarbal:13,add_new_repo:13,add_path:9,add_sect:12,add_templ:[7,12],add_template_var:[7,12],add_url_rul:13,added:[6,8,9,12,13],adding:[8,12],addit:[1,2,6,7,8,12,13],addon:13,addr:12,addrsiz:12,admin:8,administr:8,ae1bf7e3:13,af92:13,afford:6,after:[1,6,7,12,13],again:[1,2,5,13],against:[5,6],ain:13,alia:13,alibaba:[1,13],align:6,all:[0,1,2,4,5,6,7,8,11,12,13],allbut:[7,12],alloc:6,allow:[6,7,8],allow_no_valu:13,almost:4,along:[7,13],alreadi:[1,8,12,13],also:[1,5,6,7,8,9,12,13],alwai:[6,8,13],amazon:6,america:8,ami:[1,8],amount:8,anaconda:[1,4,7,8,9,11,12,13],anaconda_arg:[6,13],anaconda_cleanup:12,anaconfigurationthread:13,ancient:13,ani:[0,1,2,5,6,7,8,9,12,13],anoth:[1,6,7,12],ansibl:1,anyth:[11,13],anywher:12,api:[0,1,2,8,10,12],api_changelog:13,api_tim:13,api_url:0,api_vers:[0,2],apiv:1,app:[6,13],app_fil:6,app_nam:6,app_templ:6,appear:12,append:[0,2,6,7,8,12,13],append_initrd:12,append_queri:0,appli:[1,12,13],applianc:12,applic:[8,13],appropri:[6,12],arbitrari:[7,8],arch:[2,4,6,7,12,13],archdata:12,architectur:[4,6,7,9,12],archiv:[6,8,11,12,13],aren:[7,13],arg:[1,2,6,7,12,13],argifi:2,argpars:[2,12],argument:[0,2,12,13],argumentpars:[2,12,13],argv:12,arm:[6,12],armhfp:12,armplatform:[6,13],around:6,artifact:[6,13],assembl:13,associ:[1,2,5,12,13],assum:[12,13],atla:13,attach:12,attempt:[4,5,12,13],attr:13,attribut:[6,13],audit:13,augmentenv:12,authent:[1,13],author:[1,6,7,8,9,13],authorized_kei:8,automat:[7,8,12,13],avahi:13,avail:[1,2,5,6,8,9,13],awar:8,aws:1,aws_access_kei:1,aws_bucket:1,aws_region:1,aws_secret_kei:1,azur:[5,13],b067:13,b36e:13,b421:13,b6218e8f:13,b637c411:13,back:[1,7,12,13],backup:[12,13],bare:[6,13],base:[0,5,6,7,8,10,13],basearch:[12,13],baseimag:8,baseloraxclass:12,basenam:12,baserequesthandl:12,basesystem:13,baseurl:[6,8,9,13],bash:[4,6,8,13],basic:[1,7],bb1d:13,bcj_arch:12,bcl:[1,6,7,8,9],bd31:13,bdc:8,bec7:13,becaus:[6,7,8,13],becom:[6,8],been:[6,9,12,13],befor:[3,6,7,8,12,13],behavior:13,behind:[8,12],being:[6,7,8,13],below:[6,7,13],best:[6,7,8,13],better:12,between:[1,2,6,7,8,12,13],big:12,bin:[6,8,12],binari:[6,12],binary_output:12,bind:6,bind_mount_opt:6,bio:6,bisect:[10,12],bit:8,blob:13,block:[7,8,12,13],block_siz:13,blocksiz:12,blog:8,blueprint:[0,9,10,13],blueprint_exist:13,blueprint_nam:[2,13],blueprints_chang:2,blueprints_cmd:2,blueprints_delet:2,blueprints_depsolv:2,blueprints_diff:2,blueprints_freez:2,blueprints_freeze_sav:2,blueprints_freeze_show:2,blueprints_list:2,blueprints_push:2,blueprints_sav:2,blueprints_show:2,blueprints_tag:2,blueprints_undo:2,blueprints_workspac:2,blueprintsetupst:13,blueprintsetupstateskip:13,blueprintskip:13,bodi:[0,13],bool:[2,5,12,13],boot:[1,4,7,8,11,12,13],boot_uefi:12,bootabl:[6,7],bootdir:12,bootload:[6,8,9,13],bootloader_append:13,bootproto:6,both:[6,8,13],bound:13,boundari:13,box:6,brace:12,brace_expand:12,branch:[6,8,13],brian:[1,6,7,8,9],brianlan:13,browser:8,bucket:1,bug:[6,7,8],bugurl:[7,12],bugzilla:6,build:[2,4,6,7,8,11,12,13],build_config_ref:13,build_env_ref:13,build_id:13,build_statu:13,build_tim:13,buildarch:[7,12],builder:[6,13],buildinstal:4,buildsi:6,buildstamp:10,built:[1,7,12,13],builtin:12,bump:[8,13],bump_vers:13,bunch:12,bundl:6,bzip2:[6,12],c30b7d80:13,c75d5d62:13,c98350c89996:13,cach:[6,7,8,12],cachedir:[7,12],calcul:12,calculate_disk_s:12,call:[4,5,6,12,13],callback:[5,12,13],calledprocesserror:12,caller:13,can:[1,2,5,6,7,8,9,11,12,13],cancel:[1,2,5,6,12,13],cancel_func:12,cancel_upload:5,cannot:[0,6,7,8,13],captur:12,care:[9,12,13],cat:6,categor:8,caught:[6,13],caus:[7,8,12],cdboot:8,cdlabel:12,cdrom:9,cee5f4c20fc33ea4d54bfecf56f4ad41ad15f4f3:13,central:4,cert:12,certif:[7,8,13],cfg:[12,13],chang:[1,2,6,7,8,9,12,13],changelog:[1,13],charact:[8,12],check:[5,8,9,12,13],check_gpg:[8,13],check_kickstart:12,check_list_cas:13,check_queu:13,check_recipe_dict:13,check_required_list:13,check_ssl:[8,13],checkparam:[10,12],checksum:[6,9],checksum_typ:6,child:12,chmod:[7,12],chmod_:12,cho2:8,choos:6,chosen:[6,12,13],chown_:12,chronyd:8,chroot:[6,7,11,12],chroot_setup_cmd:6,chvt:6,cisco:13,clean:[4,6,8,12,13],cleanup:[6,12,13],cleanup_tmpdir:13,clear:[4,8,13],clearpart:6,cli:[0,3,8,10,13],client:[0,6,13],client_address:12,client_id:13,clone:[8,13],close:12,cloud:[5,6,8,13],cls:12,cmd:[8,12],cmdline:[0,10],cmdlist:12,cockpit:8,code:[7,8,12,13],collect:13,com:[1,6,7,8,9,13],combin:[2,6,13],come:13,comma:[2,12,13],command:[0,1,2,4,6,7,8,9,11,12,13],commandlin:[1,8,12],comment_prefix:13,commit:[1,2,8,13],commit_id:13,commit_recip:13,commit_recipe_directori:13,commit_recipe_fil:13,commitdetail:13,committimevalerror:13,common:[6,7],commonli:8,commun:[0,2,8],comoposit:13,compar:13,comparison:13,compat:8,complet:[4,8,12,13],compon:6,compos:[3,5,9,10,12],compose_arg:[8,13],compose_cancel:2,compose_cmd:2,compose_delet:2,compose_detail:13,compose_imag:2,compose_info:2,compose_list:2,compose_log:2,compose_metadata:2,compose_result:2,compose_start:2,compose_statu:[2,13],compose_typ:[2,8,13],compose_uuid:13,composer_cli_pars:2,composerconfig:[5,13],composerpars:13,composit:13,compress:[6,11,12,13],compress_arg:[6,13],compressarg:12,compressopt:12,comput:12,conf:[4,5,6,7,8,12,13],conf_fil:[12,13],config:[6,7,8,10,12],config_opt:6,configfil:7,configpars:13,configur:[4,5,6,7,8,9,12,13],conflict:[7,8],connect:[0,9],connectionpool:0,consist:[1,4],consol:8,construct:[8,12],constructor:13,contain:[4,7,8,9,11,12,13],content:[3,7,8,9,10,11],context:12,continu:[2,12],control:[4,8,12,13],convent:6,convers:1,convert:[1,2,6,8,12,13],copi:[1,4,6,7,8,9,11,12,13],copy_dracut_hook:12,copyin:6,copytre:12,core:6,correct:[1,2,4,6,8,12,13],correctli:[6,8,12,13],correspond:[7,12],corrupt:[5,9],could:[5,6,8],couldn:5,count:13,coupl:6,cpio:12,cpu:12,crash:12,creat:[1,4,5,7,8,11,12,13],create_ext4_runtim:12,create_gitrpm_repo:13,create_pxe_config:12,create_squashfs_runtim:12,create_upload:5,create_vagrant_metadata:12,createaddrs:12,createrepo:6,createrepo_c:[9,13],creation:[4,9,11,12,13],creation_tim:[5,13],creator:[3,8,9,10,13],credenti:1,cross:13,current:[1,4,5,6,8,12,13],custom:[4,6,9,11,13],customizations_diff:13,customize_ks_templ:13,cwd:0,d6bd:13,data:[0,4,6,12,13],datahold:[12,13],dbo:[12,13],debug:[8,9,12],decod:[12,13],decor:10,dedic:5,dee:13,default_image_nam:12,default_sect:13,defin:[5,6,8,13],delai:[8,12],delet:[0,1,2,5,6,7,8,12,13],delete_fil:13,delete_profil:5,delete_recip:13,delete_repo_sourc:13,delete_upload:5,delete_url_json:0,delimit:13,denial:[6,8],dep:13,dep_evra:13,dep_nevra:13,depend:[1,2,6,7,8,9,11,13],deploy:[8,12,13],depmod:12,depsolv:[1,2,8,13],describ:[1,6,8,13],descript:[1,6,8,12,13],deseri:5,desir:13,desktop:6,dest:[12,13],destdir:13,destfil:12,destin:[7,8,12,13],detach:12,detail:[1,2,8,13],detect:[6,12],dev:[6,7,12],devel:6,develop:[6,8,13],devic:[6,7,12],devicemapp:12,dhcp:[6,8],dialog:6,dict:[0,2,5,12,13],dict_nam:2,dict_typ:13,dictionari:13,didn:6,died:6,diff:[1,2,13],diff_list:13,differ:[1,2,5,6,8,12,13],difficult:13,dir:[6,7,12,13],direcori:12,direct:13,directli:[2,6,8,13],directori:[1,5,6,7,8,9,11,12,13],dirinstall_path:12,disabl:[7,8,12,13],disablerepo:[7,12],disassoci:13,discinfo:[7,10],disk:[1,9,12,13],disk_imag:6,disk_img:12,disk_info:6,disk_siz:12,diskimag:12,dispatch:2,displai:[1,2,5,6,8,13],disposit:0,distinct:13,distribut:[7,8],dm_attach:12,dm_detach:12,dmdev:12,dmsetup:12,dnf:[7,8,12,13],dnf_conf:13,dnf_obj:12,dnf_repo_to_file_repo:13,dnfbase:10,dnfhelper:10,dnflock:13,dnfplugin:[7,12],do_graft:12,doc:[6,8,13],document:[6,7,8,9],doe:[2,6,7,8,9,12,13],doesn:[1,2,6,7,8,12,13],doing:[6,8,13],domacboot:12,domain:8,don:[5,6,9,12,13],done:[1,12,13],doupgrad:12,down:13,download:[0,2,6,7,12,13],download_fil:0,downloadprogress:12,dracut:12,dracut_arg:[6,7,12],dracut_conf:[6,7],dracut_default:12,dracut_hook:12,dracut_hooks_path:12,drawback:6,drive:7,driven:4,driver:[4,12],drop:[8,11],dst:12,due:6,dump:13,dure:2,dyy8gj:13,e083921a7ed1cf2eec91ad12b9ad1e70ef3470b:13,e695affd:13,e6fa6db4:13,each:[1,2,5,6,7,8,12,13],easi:12,easier:6,eastern:8,ec2:6,echo:6,edit:[8,13],edk2:6,effect:8,efi:[6,8,9],efibootmgr:9,either:[6,8,12,13],el7:13,els:[7,12],emit:12,empti:[7,8,12,13],empty_lines_in_valu:13,en_u:8,enabl:[6,7,8,9,12,13],enablerepo:[7,12],encod:12,encount:[6,13],encrypt:8,end:[1,5,6,7,8,12,13],endfor:12,endif:7,endpoint:13,enforc:[6,8,13],enhanc:6,enough:12,ensur:[12,13],enter:13,entir:8,entri:[2,6,8,12,13],env_add:12,env_prun:12,environ:[6,7,8,12],epoch:[2,13],equival:12,err:12,error:[2,5,6,8,10,12],escap:12,especi:8,estim:13,estimate_s:[12,13],etc:[6,7,8,12,13],even:[6,7,13],ever:0,everi:13,everyth:[6,7,12],exact:[8,13],exactli:[8,13],examin:[6,9],exampl:[1,2,6,7,11,12,13],except:[6,7,8,12,13],exclud:12,excludepkg:[7,12],exec:6,execproduct:12,execreadlin:12,execut:[2,4,5,8,9,12],executil:10,execwithcaptur:12,execwithredirect:12,exist:[0,2,4,6,7,8,12,13],exit:[1,2,6,7,8,9,12],expand:12,expans:12,expect:[5,6,7,8,9,12,13],expected_kei:13,experi:12,expir:13,expire_sec:13,explicitli:8,explor:1,exract:13,ext4:[1,7,8,12,13],extend:8,extens:[1,7],extern:12,extra:[2,6,8,9,13],extra_boot_arg:[6,12],extract:[12,13],f15:6,f16:6,f5c2918544c4:13,f629b7a948f5:13,fail:[1,2,8,12,13],failur:[12,13],fairli:7,fakednf:12,fall:[7,13],fals:[1,2,5,6,7,8,12,13],far:6,fatal:[6,12],fatalerror:12,fe925c35e795:13,featur:6,fedora:[3,6,7,8,12,13],fedoraproject:[6,7,13],feedback:6,fetch:[0,12],few:[6,7],field:[1,2,8,13],figur:4,fila:13,file:[0,1,2,4,5,7,8,9,11,12,13],fileglob:12,filenam:[0,1,2,12,13],filesystem:[1,8,11,12,13],fill:13,filter:[12,13],filter_stderr:12,find:[0,4,5,6,12,13],find_commit_tag:13,find_field_valu:13,find_free_port:12,find_nam:13,find_ostree_root:12,find_recipe_obj:13,find_templ:12,findkernel:12,fine:8,finish:[1,2,7,8,12,13],firewal:13,firewall_cmd:13,firewalld:8,firmwar:6,first:[1,4,6,7,8,9,12,13],first_registr:13,fit:6,five:2,fix:12,flag:12,flask:13,flask_blueprint:[10,12],flatten:6,flexibl:4,fmt:12,fname:12,fobj:12,follow:[1,2,5,6,12,13],foo:13,forc:[7,8,12,13],form:[0,5,7,9,13],format:[1,2,6,8,12,13],found:[5,6,8,9,12,13],four:2,free:[7,12],freez:[1,2,13],from:[0,1,2,4,5,6,7,8,9,11,12,13],from_commit:13,front:5,frozen:[1,2],frozen_toml_filenam:2,frozenset:13,fs_imag:6,fs_label:6,fsck:12,fsimag:[6,12],fstab:6,fstype:[6,12],ftp:8,ftruncat:12,full:[0,8,9,12,13],further:12,game:13,gather:1,gener:[2,4,6,7,9,12,13],generate_module_data:12,generate_module_info:12,get:[0,5,6,8,12,13],get_all_upload:5,get_arch:12,get_base_dir:13,get_base_object:13,get_buildarch:12,get_commit_detail:13,get_compose_typ:13,get_default:13,get_default_servic:13,get_dnf_base_object:12,get_extra_pkg:13,get_filenam:0,get_firewall_set:13,get_image_nam:13,get_iso_label:12,get_kernel_append:13,get_keyboard_layout:13,get_languag:13,get_loop_nam:12,get_repo_descript:13,get_repo_sourc:13,get_revision_from_tag:13,get_servic:13,get_source_id:13,get_timezone_set:13,get_upload:5,get_url_json:0,get_url_json_unlimit:0,get_url_raw:0,gfile:13,ggit:13,gib:[6,7,12],gid:[8,13],git:[6,13],gitarchivetarbal:13,github:6,gitlock:13,gitrepo:13,gitrpm:[10,12],gitrpmbuild:13,given:[0,5,12,13],glanc:6,glob:[7,8,12,13],glusterf:13,gnome:6,gnu:13,goe:[4,7,12],going:[1,6],gonna:13,good:[6,9,12],googl:[1,8],gpg:[8,13],gpgcheck:8,gpgkei:[8,13],gpgkey_url:[8,13],gplv3:13,graft:12,green:13,group:[1,6,12,13],group_nam:13,group_typ:13,grow:6,growpart:6,grub2:[6,8,9],grub:12,gui:8,gzip:[6,12],had:6,handl:[2,6,7,8,12],handle_api_result:2,handler:12,happen:[6,7,12],hard:13,hardlink:12,has:[1,2,5,6,8,11,12,13],hash:[1,2,8,13],hasn:9,have:[1,2,5,6,7,8,9,12,13],haven:6,hawkei:13,hda:1,head:[8,13],head_commit:13,header:[0,8,13],hello:6,help:[0,6,7,9,10,12],helper:13,here:[4,6,7,8,9,11,13],higer:13,highbank:6,higher:7,histori:[8,13],hold:13,home:[6,8],homepag:13,hook:12,host:[0,6,7,8,12,13],hostnam:[8,13],how:[4,12],howev:[6,7,8],http:[0,1,2,6,7,8,12,13],http_client:10,httpconnect:0,httpconnectionpool:0,httpd:8,human:2,hw_random:12,hwmon:12,hybridiso:9,hyper:1,i386:12,ia64:12,iam:1,id_rsa:8,idea:[4,6,9],ideal:12,identifi:[2,7],ids:13,ignor:[5,12],ignore_corrupt:5,ignore_miss:5,imag:[2,3,4,5,7,9,12,13],image_nam:[5,6,8,13],image_path:[5,13],image_s:13,image_size_align:6,image_typ:[6,12],images_dir:12,imap:8,img:[6,7,11,12],img_mount:12,img_siz:12,imgutil:10,immedi:8,immut:[8,13],implantisomd5:12,implement:[11,12],includ:[0,1,2,5,6,7,8,9,11,13],inclus:13,incom:12,increment:13,indent:2,index:[3,13],indic:12,individu:2,info:[1,2,8,9,13],inform:[1,2,4,5,7,8,13],init:[6,8,12],init_file_log:12,init_stream_log:12,initi:12,initramf:[6,7,12,13],initrd:[6,7,12],initrd_address:12,initrd_path:12,inject:8,inline_comment_prefix:13,input:[6,9,12],input_iso:9,inroot:12,insecur:6,insert:13,insid:[6,12,13],insort_left:13,inst:9,instal:[1,2,4,9,10,11,13],install_log:12,installclass:11,installerror:12,installimg:[11,12],installinitrd:12,installkernel:12,installpkg:[7,11,12,13],installroot:[7,12],installtre:12,installupgradeinitrd:12,instanc:[5,6,13],instead:[1,2,5,6,7,8,13],instroot:4,instruct:6,insuffici:12,integ:13,interact:1,interfac:8,interfer:7,intermedi:1,interpol:13,intrd:12,introduct:3,invalid:[5,13],ioerror:13,is_cancel:5,is_commit_tag:13,is_image_mount:12,is_parent_diff:13,iserror:12,isfin:[7,12],isn:[6,12,13],iso:[1,4,12,13],iso_nam:6,iso_path:12,isoinfo:12,isolabel:12,isolinux:12,isomountpoint:12,issu:8,item:[2,12,13],iter:[12,13],its:[5,6,12,13],itself:8,jboss:13,job:13,job_creat:13,job_finish:13,job_start:13,joinpath:12,json:[0,1,2,6,8,12,13],just:[5,11,12,13],kbyte:13,kdir:12,keep:[1,6,12,13],keepglob:12,kei:[1,2,5,8,12,13],kernel:[6,7,9,12,13],kernel_append:13,kernel_arg:[6,12],keyboard:[8,13],keyboard_cmd:13,keymap:8,kib:13,kickstart:[8,12,13],kickstartpars:12,kill:[6,12],knowledg:4,known:2,kpartx:[6,12],kpartx_disk_img:12,ks_path:12,ks_templat:13,ksflatten:6,kubernet:13,kvm:[1,6],kwarg:[12,13],label:[6,12],lambda:12,lane:[1,6,7,8,9],lang:13,lang_cmd:13,languag:[8,13],larg:[8,13],last:[1,2,9,12,13],later:[12,13],latest:[6,13],launch:8,layout:13,lazi:12,lead:[0,12],least:[6,12],leav:[7,8,12,13],left:[8,12,13],leftmost:13,leftov:[6,12],len:13,less:13,level:[6,7,8,12,13],lib64_arch:12,lib:[5,8,12,13],lib_dir:5,librari:4,libus:13,libvirt:6,licens:13,lift:[1,10],light:7,like:[1,5,6,7,8,9,11,12,13],limit:[0,6,8,12,13],line:[2,4,8,12,13],link:12,linktre:12,linux:[6,7,12],list:[1,2,4,5,6,7,8,12,13],list_branch_fil:13,list_commit:13,list_commit_fil:13,list_provid:5,listen:[1,8,12],live:[1,4,8,12,13],live_image_nam:12,live_rootfs_s:6,livecd:12,livemedia:[3,8,9,12,13],liveo:[7,12],livesi:6,livetemplaterunn:12,lmc:[6,12],lmc_parser:12,load:[5,12,13],load_profil:5,load_set:5,local:[1,6,12,13],localectl:8,localhost:[12,13],locat:[6,7,13],lock:[8,13],lock_check:13,log:[1,2,6,7,12,13],log_check:12,log_error:12,log_output:12,log_path:12,log_request_handler_class:12,log_selinux_st:12,logdir:12,logfil:[1,6,7,8,12],logger:12,logic:7,logmonitor:12,lognam:12,logo:7,logrequesthandl:12,logserv:12,longer:[6,7,8,13],look:[1,4,5,6,8,11,13],loop:[6,7,12],loop_attach:12,loop_detach:12,loop_dev:12,loop_waitfor:12,loopdev:12,loopx:12,loopxpn:12,lorax:[1,5,6,9,11,12,13],lorax_composer_pars:13,lorax_pars:12,lorax_templ:6,loraxdir:12,loraxdownloadcallback:12,loraxrpmcallback:12,loraxtempl:12,loraxtemplaterunn:[7,12],lose:6,losetup:12,lost:13,low:12,lowercas:12,lowest:12,lpar:12,lst:[2,13],ltmpl:[7,10],lvm2:12,lzma:[6,12],mac:[6,7,9],macboot:[6,7],machin:9,made:[8,12],mai:[1,6,7,8,9,12,13],mail:6,main:2,maintain:4,make:[1,5,6,7,8,9,12,13],make_:8,make_appli:12,make_compos:13,make_disk:8,make_dnf_dir:13,make_git_rpm:13,make_imag:12,make_live_imag:12,make_livecd:12,make_owned_dir:13,make_queue_dir:13,make_runtim:12,make_setup_st:13,make_tar_disk:12,makestamp:4,maketreeinfo:4,mako:[4,6,7,12],manag:[1,5],mandatori:[8,13],mani:13,manpag:[6,7],manual:13,map:2,mark:5,mask:12,master:13,match:[1,6,8,12,13],maximum:13,maxretri:12,mbr:6,meant:[5,12,13],meantim:1,mechan:8,media:[6,12],megabyt:6,member:[1,6],memlimit:12,memori:[6,12],memtest86:6,mention:12,messag:[8,9,12,13],metadata:[1,2,6,7,8,12,13],metalink:[8,13],method:[6,8,12,13],mib:[6,12,13],mime:13,mind:[6,13],minim:[6,8,12],minimum:[5,6,13],minut:6,mirror:[6,12,13],mirrorlist:[7,8,12,13],mirrormanag:6,miss:[5,12,13],mix:4,mkbtrfsimg:12,mkcpio:12,mkdir:[6,7,12],mkdosimg:12,mkext4img:12,mkf:12,mkfsarg:12,mkfsimag:12,mkfsimage_from_disk:12,mkhfsimg:12,mkisof:9,mkksiso:3,mknod:6,mkqcow2:12,mkqemu_img:12,mkrootfsimg:12,mkspars:12,mksquashf:12,mktar:12,mnt:[8,12],mock:[1,8],mockfil:8,moddir:12,mode:[1,6,7,12,13],modeless:12,modifi:[6,9,12,13],modul:[1,3,4,7,10],module_nam:13,module_nv:13,modules_cmd:2,modules_info:13,modules_list:13,monitor:[6,10,13],more:[1,4,6,8,12],most:[1,2,6,8,13],mount:[6,8,9,10],mount_boot_part_over_root:12,mount_dir:12,mount_ok:12,mountarg:12,mountpoint:[6,12],move:[7,8,12,13],move_compose_result:[8,13],msg:[12,13],much:12,multi:6,multipl:[1,2,6,7,8,9,12,13],must:[1,6,7,8,11,12,13],mvebu:6,myconfig:12,name:[2,5,9,12,13],namespac:2,need:[1,2,6,7,8,9,12,13],neither:13,network:[6,7,8,9,12],never:12,nevra:[2,13],new_image_nam:5,new_item:13,new_recip:13,new_repo_sourc:13,new_set:5,newer:6,newest:[1,2,13],newli:12,newlin:12,newrecipegit:13,newrun:12,next:[12,13],nice:2,noarch:[8,13],node:[6,7],nomacboot:[6,7],non:[7,8,12,13],none:[0,5,6,8,12,13],nop:12,norm:2,normal:[1,6,7,9,11],north:8,nosmt:8,nosuchpackag:12,note:[6,7,12,13],noth:[2,12,13],noupgrad:7,noverifi:7,noverifyssl:[7,12],novirt:6,novirt_cancel_check:12,novirt_instal:[8,12,13],now:[6,11,12,13],nspawn:[6,7],ntp:8,ntpserver:[8,13],number:[1,2,6,7,8,12,13],numer:8,nvr:7,object:[0,1,5,12,13],observ:6,occas:12,occur:12,oci_config:6,oci_runtim:6,octalmod:12,off:8,offset:[0,13],oid:13,old:[6,7,12,13],old_item:13,old_recip:13,old_vers:13,older:[6,7],omap:6,omit:8,onc:[1,6,7,8,13],one:[1,2,6,7,8,11,12,13],ones:[7,8,12,13],onli:[1,2,6,7,8,9,12,13],onto:7,open:[8,13],open_or_create_repo:13,openh264:13,openssh:8,openstack:[1,8],oper:[4,6,8,13],opt:[2,8,12,13],option:[1,4,5,6,7,8,12,13],order:[1,4,7,8,13],ordereddict:13,org:[6,7,8,13],origin:[0,6,8,9,13],ostre:[6,12],other:[4,6,7,8,12,13],otherwis:[7,8,12,13],ouput:13,out:[1,4,8,9,12,13],outfil:12,output:[1,2,6,7,10],output_iso:9,outputdir:[7,12],outroot:12,outsid:12,over:[8,11],overhead:12,overrid:[6,7,8,12,13],overridden:8,overwrit:[1,2,5,8,13],overwritten:12,ovmf:6,ovmf_path:[6,12],own:[6,7,8,13],owner:[8,13],ownership:[8,13],p_dir:13,pacag:12,packag:[1,4,6,7,10,11],package_nam:13,package_nv:13,packagedir:12,packagenevra:2,page:3,param1:0,param2:0,param:[12,13],paramat:11,paramet:[0,2,5,12,13],parent:13,pars:[12,13],parser:12,part:[2,6,7,11,12,13],particular:12,partit:[1,6,12],partitin:6,partitionmount:12,pass:[1,5,6,7,8,9,11,12,13],passwd:6,password:[6,8,13],pat:12,patch:[8,13],path:[0,1,2,5,6,7,8,9,12,13],pathnam:[9,12],pattern:[5,12],payload:12,pcritic:12,pdebug:12,per:[12,13],permiss:[8,13],perror:12,phys_root:12,physic:12,pick:[1,12],pid:[6,12],pinfo:12,ping:13,pivot:12,pkg:[2,12,13],pkg_to_build:13,pkg_to_dep:13,pkg_to_project:13,pkg_to_project_info:13,pkgglob:12,pkglistdir:12,pkgname:11,pkgsizefil:12,pki:13,place:[1,6,7,11,12,13],placehold:[5,13],plai:13,plain:[6,7,8,12,13],plan:9,platform:[6,13],play0ad:13,playbook:[1,5],playbook_path:5,pleas:12,plugin:7,plugin_conf:6,point:[4,6,8,12,13],pool:8,popen:[12,13],popul:[12,13],port:[0,6,7,8,12,13],pos:13,posit:13,possibl:[2,6,8,12,13],post:[0,6,8,12,13],post_url:0,post_url_json:0,post_url_toml:0,postfix:8,postinstal:12,postun:12,potenti:5,powerpc:12,ppc64:12,ppc64le:[11,12],ppc:11,pre:[6,8,9,12,13],precaut:1,preexec_fn:12,prefix:[6,8,12,13],prepar:13,prepare_commit:13,prepend:13,present:[4,6,13],preserv:[9,12],pretti:[8,12],pretty_dict:2,pretty_diff_entri:2,prettycommitdetail:2,preun:12,prevent:[7,13],previou:[8,12,13],previous:[1,4,6],primari:[6,8],primarili:8,print:[1,2,9],privileg:8,probabl:7,problem:[1,4,12,13],proc:12,procedur:12,process:[1,2,4,5,6,7,8,11,12,13],produc:[4,6,8,13],product:[1,3,7,12,13],profil:[2,5,13],program:[1,2,6,7,8,12,13],progress:[0,1,2,12,13],proj:13,proj_to_modul:13,project:[0,1,6,8,10,12],project_info:13,project_nam:13,projects_cmd:2,projects_depsolv:13,projects_depsolve_with_s:13,projects_info:[2,13],projects_list:[2,13],projectserror:13,prompt:9,pronounc:13,properti:[12,13],protocol:8,provid:[0,4,6,7,10,12,13],provider_nam:[5,13],providers_cmd:2,providers_delet:2,providers_info:2,providers_list:2,providers_push:2,providers_sav:2,providers_show:2,providers_templ:2,proxi:[7,8,12,13],pub:[6,7,8],pubkei:6,pull:[4,6,7],pungi:4,purpos:[6,8],push:[1,2],put:[8,11,12,13],pwarn:12,pxe:12,pxeboot:7,pyanaconda:11,pykickstart:[12,13],pylorax:[4,7,8,10,11],pyo:12,python:[4,7,12,13],pythonpath:6,qcow2:[1,6,12],qemu:[1,12],qemu_arg:6,qemu_cmd:12,qemuinstal:12,queri:[0,2],queu:[1,2,13],queue:[2,8,10,12],queue_statu:13,quot:12,race:12,rais:[0,5,12,13],raise_err:12,ram:[6,12],random:[6,12],rang:12,rare:12,raw:[0,1,2,6,13],rawhid:[6,7],rdo:6,re_test:12,react:8,read:[4,6,12,13],read_commit:13,read_commit_spec:13,read_recipe_and_id:13,read_recipe_commit:13,readabl:2,readi:[5,12,13],readm:13,ready_upload:5,real:[6,8,12],realli:[6,7,12],reason:[6,12],reboot:8,rebuild:[6,7,12],rebuild_initrd:12,rebuild_initrds_for_l:12,recent:[1,2,13],recip:[10,12],recipe_dict:13,recipe_diff:13,recipe_filenam:13,recipe_from_dict:13,recipe_from_fil:13,recipe_from_toml:13,recipe_kei:13,recipe_nam:13,recipe_path:13,recipe_str:13,recipeerror:13,recipefileerror:13,recipegit:13,recipegroup:13,recipemodul:13,recipepackag:13,recommend:[6,8],record:1,recurs:12,redhat:[1,6,7,8,9],redirect:[6,12],reduc:8,ref:[8,13],refer:[1,8,9,13],referenc:8,refus:6,regener:9,regex:[5,10,12],region:1,regist:13,register_blueprint:13,rel:12,relat:[7,8,13],releas:[1,2,4,6,7,8,12,13],releasev:[6,8,12,13],relev:13,reli:4,reliabl:6,remain:[2,7,8],remaind:13,rememb:8,remov:[1,2,4,6,7,8,12,13],remove_temp:12,removefrom:[7,12],removekmod:[7,12],removepkg:[7,12],renam:[6,12,13],repl:12,replac:[4,6,7,8,11,12,13],repo1:6,repo2:6,repo:[4,7,12,13],repo_dir:13,repo_file_exist:13,repo_to_k:13,repo_to_sourc:13,repo_url:6,repodata:[6,9,13],repodict:13,repoid:13,report:[6,7,8,13],repositori:[7,8,12,13],repres:5,represent:[5,13],reproduc:13,reqpart:[6,12],request:[0,8,12,13],requir:[1,6,8,12,13],rerun:13,rescu:6,reserv:6,reset:[1,2,5,12,13],reset_handl:12,reset_lang:12,reset_upload:5,resolv:12,resolve_playbook_path:5,resolve_provid:[5,13],resort:12,resource_group:13,respond:8,respons:[0,1,12],rest:[8,12],restart:[8,13],restor:13,result:[0,2,6,7,8,12,13],result_dir:6,resultdir:6,results_dir:[12,13],retain:8,reticul:12,retriev:[8,13],retrysleep:12,retun:13,returncod:12,revert:[1,2,13],revert_fil:13,revert_recip:13,revis:13,revisor:4,revpars:13,rexist:12,rglob:12,rhel7:[3,6,13],rhel8:3,rhel:6,rng:6,roll:13,root:[1,2,4,6,7,8,9,12,13],root_dir:13,rootdir:12,rootf:[6,7,12],rootfs_imag:12,rootfs_siz:7,rootm:6,rootpw:[6,13],roughli:12,round:[12,13],round_to_block:12,rout:[0,8,12],rpm:[4,6,8,12,13],rpmbuild:13,rpmfluff:13,rpmname:[8,13],rpmreleas:[8,13],rpmversion:[8,13],rtype:13,rule:[1,13],run:[1,2,6,8,9,11,12,13],run_creat:12,run_pkg_transact:[7,12],runcmd:[7,12],runcmd_output:12,rundir:12,runner:12,runtim:[6,11,12],runtimebuild:[11,12],runtimeerror:[0,5,12,13],rxxx:13,s390x:12,safe:[8,12],samba:13,same:[1,6,7,8,12,13],sampl:12,satisfi:13,save:[0,1,2,5,7,8,12,13],save_set:5,sbin:[6,12],scene:8,schedul:13,script:[4,6,12,13],scriptlet:12,search:[3,7,12,13],second:[6,13],secondari:8,secret:[1,13],section:[1,6,8,12,13],secur:1,see:[1,6,7,9,12,13],seem:12,select:[1,2,5,6,7,8,12,13],self:[5,8,12,13],selinux:[6,8,12],semver:[8,13],send:[0,1,5],separ:[2,8,12,13],sequenc:12,serial:5,serializ:5,server:[0,1,2,8,10,12],servic:[1,2,7,12,13],services_cmd:13,set:[1,2,4,5,6,7,8,9,12,13],set_statu:5,setenforc:7,setenv:12,setup:[6,7,8,12,13],setup_log:12,sever:[6,11,13],sha256:6,shallow:12,share:[1,6,7,8,11,12,13],share_dir:[5,13],sharedir:[7,8,12],sharpest:13,shell:8,ship:7,shlex:12,shortnam:12,should:[0,1,6,7,8,12,13],should_exit_now:2,show:[1,2,6,7,8,9,12],show_json:2,shown:1,shutdown:[6,12],sig:13,sig_dfl:12,sig_ign:12,sigint:5,sign:[8,12,13],signal:12,signific:8,similar:[7,8],simpl:[2,7,8],simple_test:12,simplerpmbuild:13,simplest:9,simpli:8,simul:2,sinc:[6,8,13],singl:[2,6,13],singleton:12,site:6,situat:8,size:[1,2,6,7,12,13],skip:[6,7,12,13],skip_brand:12,skip_rul:13,slice:13,slightli:6,slow:6,small:12,smp:6,snake_cas:5,socket:[0,1,2,8],socket_path:[0,2],socketserv:12,softwar:13,solut:6,solv:13,some:[0,1,4,6,7,8,12,13],somebodi:13,someplac:8,someth:[4,6,7,8,12,13],sometim:6,sort:[7,13],sound:[7,12],sourc:[0,1,5,7,9,10,12,13],source_glob:13,source_id:13,source_nam:13,source_path:13,source_ref:13,source_to_repo:13,source_to_repodict:13,sources_add:2,sources_cmd:2,sources_delet:2,sources_info:2,sources_list:2,sourcesdir:13,space:[2,7,8,12,13],sparingli:13,spars:[6,12],speak:[4,7],spec:13,special:[7,13],specif:[1,5,6,7,8,11,12,13],specifi:[0,5,6,8,12,13],speed:[1,6],spin:6,spline:12,split:12,split_and_expand:12,squashf:[6,12],squashfs_arg:12,squashfs_onli:12,src:[3,6,12],srcdir:12,srcglob:12,srv:8,ssh:[6,8,13],sshd:[6,8],sshkei:13,ssl:[7,12],sslverifi:12,stage2:12,stage:[4,6],standard:[12,13],start:[1,2,5,6,7,8,12,13],start_build:13,start_queue_monitor:13,start_upload_monitor:5,startprogram:12,startup:8,state:[1,5,6,8,12,13],statement:12,statu:[0,5,8,10,12],status_callback:5,status_cmd:2,status_filt:13,stderr:12,stdin:12,stdout:[12,13],step:[4,6,9],stick:[8,9],still:[6,8,12],stop:[6,8],storag:[1,2,6,8,12,13],storage_account_nam:13,storage_contain:13,store:[1,5,6,7,8,12,13],str1:2,str2:2,str:[0,2,5,12,13],strang:6,stream:13,strict:13,strictli:7,string:[0,2,5,8,9,12,13],string_low:12,stuck:6,stuff:6,style:12,sub:12,subclass:13,subdirectori:13,submit:13,submodul:10,submount:12,subpackag:10,subprocess:12,subscription_id:13,subset:13,substitut:[6,7,13],succe:13,success:[1,12,13],successfulli:[1,5],sudo:[6,8],suffix:12,suit:[1,8],suitabl:[12,13],summari:[5,8,13],support:[1,2,4,6,7,9,11,13],supported_typ:13,sure:[1,5,6,7,8,9,12,13],suspect:6,swap:6,symlink:[7,12,13],sys:[2,12],sys_root_dir:12,sysimag:12,syslinux:6,sysroot:12,system:[1,6,7,8,9,12,13],system_sourc:13,systemctl:[7,8,12],systemd:[6,7,8,12],sysutil:10,tag:[1,2,7,8,13],tag_file_commit:13,tag_recipe_commit:13,tail:13,take:[2,6,8,11,12,13],take_limit:13,talk:[0,2],tar:[1,2,8,9,13],tar_disk_nam:6,tar_img:12,tarbal:12,tarfil:[6,12],target:[6,7,12],tcp:[8,12],tcpserver:12,tear:13,tegra:6,tell:7,telnet:8,telnetd:8,tempdir:12,templat:[1,2,4,6,8,11,12,13],template_fil:12,templatedir:12,templatefil:12,templaterunn:12,temporari:[1,2,4,6,7,8,9,12,13],tenant:13,termin:[6,12],test:[1,6,8,9,13],test_config:13,test_mod:13,test_templ:13,testmod:[1,2],text:[7,8,13],textiowrapp:12,than:[6,8,12,13],thei:[1,6,7,8,13],thelogg:12,them:[4,7,8,12,13],therefor:8,thi:[0,1,2,5,6,7,8,9,11,12,13],thing:[4,6,12,13],those:[4,11,13],though:[4,13],thread:[5,6,8,12,13],three:[2,8],thu:12,ti_don:12,ti_tot:12,time:[6,7,8,9,11,12,13],timedatectl:8,timeout:[0,6,12],timestamp:[10,12],timestamp_dict:13,timezon:13,timezone_cmd:13,titl:[12,13],tmp:[6,7,8,12,13],tmpdir:[12,13],tmpl:[11,12,13],tmux:8,to_commit:13,token:12,told:[7,13],toml:[0,1,2,5,8,10,12],toml_dict:13,toml_filenam:2,tomldecodeerror:13,tomlerror:13,tool:[1,4,6,7,8,9,13],top:[6,7,8,11,12,13],total:[6,13],total_drpm:12,total_fil:12,total_fn:0,total_s:12,touch:12,trace:12,traceback:12,track:[1,13],trail:13,transact:12,transactionprogress:12,transmogrifi:12,trash:6,treat:[8,12],tree:[4,6,7,11,12,13],treebuild:[10,11,13],treeinfo:[7,10],tri:[1,6,12,13],truckin:12,ts_done:12,ts_total:12,tty1:6,tty3:6,tui:6,tupl:[2,12,13],turn:4,two:[2,5,13],type:[0,1,2,5,6,9,12],typic:12,ucfg:5,udev_escap:12,udp:8,uefi:[7,9],uid:[8,13],umask:12,umount:[6,8,12],uncompress:13,undelet:13,under:[1,6,7,8,12,13],understand:8,undo:[1,2,13],unexpectedli:7,unicodedecodeerror:12,uniqu:[1,13],unit:[8,12],unix:[0,2,8,13],unix_socket:10,unixhttpconnect:0,unixhttpconnectionpool:0,unknown:12,unless:[12,13],unmaintain:4,unmount:[6,12],unneed:[4,7,8,12,13],unpack:4,until:[8,12],untouch:12,unus:[2,6],upd:4,updat:[2,3,5,6,7,8,9,12,13],update_vagrant_metadata:12,upgrad:12,upload:[0,6,8,10,13],upload_cancel:2,upload_cmd:2,upload_delet:2,upload_id:13,upload_info:2,upload_list:2,upload_log:[2,5],upload_pid:5,upload_reset:2,upload_start:2,upload_uuid:13,upstream:13,upstream_vc:13,url:[0,6,7,8,9,12,13],url_prefix:13,urllib3:0,usabl:6,usag:[1,6,7,8,9,12],usb:9,usbutil:12,use:[0,1,2,5,6,7,8,9,12,13],used:[1,2,4,6,7,8,9,12,13],useful:[5,6,12],user:[1,2,7,12,13],user_dracut_arg:12,useradd:8,uses:[5,6,7,8,12,13],using:[1,2,6,7,8,9,11,12,13],usr:[1,6,7,8,11,12,13],usual:[6,8,13],utc:[8,13],utf:[8,12],util:[0,6,10,12],uuid:[1,2,5,8,13],uuid_add_upload:13,uuid_cancel:13,uuid_delet:13,uuid_dir:13,uuid_get_upload:13,uuid_imag:13,uuid_info:13,uuid_log:13,uuid_ready_upload:13,uuid_remove_upload:13,uuid_schedule_upload:13,uuid_statu:13,uuid_tar:13,v0_api:13,v0_blueprints_chang:13,v0_blueprints_delet:13,v0_blueprints_delete_workspac:13,v0_blueprints_depsolv:13,v0_blueprints_diff:13,v0_blueprints_freez:13,v0_blueprints_info:13,v0_blueprints_list:13,v0_blueprints_new:13,v0_blueprints_tag:13,v0_blueprints_undo:13,v0_blueprints_workspac:13,v0_compose_cancel:13,v0_compose_delet:13,v0_compose_fail:13,v0_compose_finish:13,v0_compose_imag:13,v0_compose_info:13,v0_compose_log:13,v0_compose_log_tail:13,v0_compose_metadata:13,v0_compose_queu:13,v0_compose_result:13,v0_compose_start:13,v0_compose_statu:13,v0_compose_typ:13,v0_modules_info:13,v0_modules_list:13,v0_projects_depsolv:13,v0_projects_info:13,v0_projects_list:13,v0_projects_source_delet:13,v0_projects_source_info:13,v0_projects_source_list:13,v0_projects_source_new:13,v1_compose_fail:13,v1_compose_finish:13,v1_compose_info:13,v1_compose_queu:13,v1_compose_start:13,v1_compose_statu:13,v1_compose_uploads_delet:13,v1_compose_uploads_schedul:13,v1_projects_source_info:13,v1_projects_source_new:13,v1_providers_delet:13,v1_providers_sav:13,v1_upload_cancel:13,v1_upload_info:13,v1_upload_log:13,v1_upload_provid:13,v1_upload_reset:13,vagrant:12,vagrant_metadata:6,vagrantfil:6,valid:[5,8,12,13],validate_set:5,valu:[2,5,6,8,12,13],valueerror:[5,13],valuetok:12,variabl:[6,7,12,13],variant:12,variou:[12,13],vcpu:[6,12],verbatim:6,veri:6,verifi:[1,7,12],version:[0,1,2,4,6,7,8,12,13],vhd:[1,13],via:[6,7,8],video:12,view:[1,13],view_func:13,virt:[12,13],virt_instal:12,virtio:12,virtio_consol:12,virtio_host:12,virtio_port:12,virtual:[6,12],vmdk:1,vmlinuz:[6,12],vnc:[6,12],volid:[6,7,9,12],volum:[6,7,9],vsphere:1,wai:[1,2,6,7,8,13],wait:[1,12,13],want:[1,6,8,9,13],warfar:13,warn:[12,13],wasn:6,watch:6,web:[6,8],websit:6,weight:7,welcom:6,welder:8,weldr:[1,8,13],well:[6,7,8,9,12,13],were:[5,12,13],what:[0,4,5,6,7,8,12,13],whatev:13,wheel:[6,8],when:[1,5,6,7,8,9,12,13],whenev:12,where:[1,6,7,8,12,13],whether:[2,5,12,13],which:[1,2,4,5,6,7,8,11,12,13],whitespac:12,who:6,whole:12,widest:8,widget:8,wildcard:8,winnt:12,wipe:9,with_cor:13,with_rng:6,without:[6,7,8,9,13],word:12,work:[12,13],work_dir:12,workdir:[7,12],workflow:4,workspac:[1,2,10,12],workspace_delet:13,workspace_dir:13,workspace_read:13,workspace_writ:13,workstat:7,world:[6,13],would:[1,6,8,9,11,12],wrapper:13,write:[4,12,13],write_commit:13,write_fil:13,write_ks_group:13,write_ks_root:13,write_ks_us:13,write_timestamp:13,writepkglist:12,writepkgs:12,written:[4,6,8,12],wrong:12,wrote:13,wwood:12,www:13,x86:[7,11,12,13],x86_64:[6,7,9,12,13],xattr:12,xfce:6,xfsprog:12,xml:6,xorrisof:[7,9],xxxx:6,xxxxx:6,yield:13,you:[1,6,7,8,9,11,12,13],your:[6,7,8,11,13],yourdomain:6,yum:[4,6,8,13],yumbas:13,yumlock:13,zero:[12,13],zerombr:6},titles:["composer package","composer-cli","composer.cli package","Welcome to Lorax's documentation!","Introduction to Lorax","lifted package","livemedia-creator","Lorax","lorax-composer","mkksiso","src","Product and Updates Images","pylorax package","pylorax.api package"],titleterms:{"default":[6,7],"import":8,"new":13,AWS:1,Adding:[8,9,13],The:7,Using:6,add:8,ami:6,anaconda:6,api:13,applianc:6,argument:[1,6,7,8,9],atom:6,base:12,befor:4,bisect:13,blueprint:[1,2,8],boot:[6,9],branch:3,brand:7,build:1,buildstamp:12,checkparam:13,cleanup:7,cli:[1,2],cmdline:[1,2,6,7,8,9,12,13],compos:[0,1,2,8,13],config:[5,13],contain:6,content:[0,2,5,12,13],creat:[6,9],creation:[6,7],creator:[6,12],custom:[7,8],debug:6,decor:12,discinfo:12,disk:[6,8],dnfbase:[12,13],dnfhelper:12,docker:6,document:3,download:1,dracut:[6,7],dvd:[8,9],edit:1,error:13,exampl:8,executil:12,exist:1,file:6,filesystem:[6,7],firewal:8,flask_blueprint:13,git:8,gitrpm:13,group:8,hack:6,help:2,how:[6,7,8,9],http_client:0,imag:[1,6,8,11],imgutil:12,indic:3,initi:6,insid:7,instal:[6,7,8,12],introduct:4,iso:[6,7,8,9],kernel:8,kickstart:[6,9],lift:5,live:6,liveimg:9,livemedia:6,local:8,log:8,lorax:[3,4,7,8],ltmpl:12,mkksiso:9,mock:[6,7],modul:[0,2,5,8,12,13],monitor:[1,12],mount:12,name:[1,6,7,8],note:8,oci:6,open:6,openstack:6,option:9,other:3,output:[8,12,13],packag:[0,2,5,8,9,12,13],partit:8,posit:[1,7,8,9],postinstal:7,problem:6,product:11,profil:1,project:[2,13],provid:[1,2,5],proxi:6,pxe:6,pylorax:[12,13],qemu:6,queue:[5,13],quickstart:[6,7,8],recip:13,regex:13,repo:[6,8,9],repositori:6,requir:7,respons:13,result:1,rout:13,run:7,runtim:7,secur:8,server:13,servic:8,sourc:[2,8],squashf:7,src:10,sshkei:8,statu:[1,2,13],submodul:[0,2,5,12,13],subpackag:[0,12],support:8,sysutil:12,tabl:3,tar:6,templat:7,thing:8,timestamp:13,timezon:8,tmpl:7,toml:13,treebuild:12,treeinfo:12,type:[8,13],uefi:6,unix_socket:0,updat:11,upload:[1,2,5],user:[6,8],util:[2,13],vagrant:6,variant:7,virt:6,welcom:3,work:[6,7,8,9],workspac:13}}) \ No newline at end of file +Search.setIndex({docnames:["composer","composer-cli","composer.cli","index","intro","lifted","livemedia-creator","lorax","lorax-composer","mkksiso","modules","product-images","pylorax","pylorax.api"],envversion:{"sphinx.domains.c":2,"sphinx.domains.changeset":1,"sphinx.domains.citation":1,"sphinx.domains.cpp":3,"sphinx.domains.index":1,"sphinx.domains.javascript":2,"sphinx.domains.math":2,"sphinx.domains.python":2,"sphinx.domains.rst":2,"sphinx.domains.std":1,"sphinx.ext.intersphinx":1,"sphinx.ext.todo":2,"sphinx.ext.viewcode":1,sphinx:56},filenames:["composer.rst","composer-cli.rst","composer.cli.rst","index.rst","intro.rst","lifted.rst","livemedia-creator.rst","lorax.rst","lorax-composer.rst","mkksiso.rst","modules.rst","product-images.rst","pylorax.rst","pylorax.api.rst"],objects:{"":{composer:[0,0,0,"-"],lifted:[5,0,0,"-"],pylorax:[12,0,0,"-"]},"composer.cli":{blueprints:[2,0,0,"-"],cmdline:[2,0,0,"-"],compose:[2,0,0,"-"],help:[2,0,0,"-"],main:[2,1,1,""],modules:[2,0,0,"-"],projects:[2,0,0,"-"],providers:[2,0,0,"-"],sources:[2,0,0,"-"],status:[2,0,0,"-"],upload:[2,0,0,"-"],utilities:[2,0,0,"-"]},"composer.cli.blueprints":{blueprints_changes:[2,1,1,""],blueprints_cmd:[2,1,1,""],blueprints_delete:[2,1,1,""],blueprints_depsolve:[2,1,1,""],blueprints_diff:[2,1,1,""],blueprints_freeze:[2,1,1,""],blueprints_freeze_save:[2,1,1,""],blueprints_freeze_show:[2,1,1,""],blueprints_list:[2,1,1,""],blueprints_push:[2,1,1,""],blueprints_save:[2,1,1,""],blueprints_show:[2,1,1,""],blueprints_tag:[2,1,1,""],blueprints_undo:[2,1,1,""],blueprints_workspace:[2,1,1,""],dict_names:[2,1,1,""],prettyCommitDetails:[2,1,1,""],pretty_dict:[2,1,1,""],pretty_diff_entry:[2,1,1,""]},"composer.cli.cmdline":{composer_cli_parser:[2,1,1,""]},"composer.cli.compose":{compose_cancel:[2,1,1,""],compose_cmd:[2,1,1,""],compose_delete:[2,1,1,""],compose_image:[2,1,1,""],compose_info:[2,1,1,""],compose_list:[2,1,1,""],compose_log:[2,1,1,""],compose_logs:[2,1,1,""],compose_metadata:[2,1,1,""],compose_ostree:[2,1,1,""],compose_results:[2,1,1,""],compose_start:[2,1,1,""],compose_status:[2,1,1,""],compose_types:[2,1,1,""],get_parent:[2,1,1,""],get_ref:[2,1,1,""],get_size:[2,1,1,""]},"composer.cli.modules":{modules_cmd:[2,1,1,""]},"composer.cli.projects":{projects_cmd:[2,1,1,""],projects_info:[2,1,1,""],projects_list:[2,1,1,""]},"composer.cli.providers":{providers_cmd:[2,1,1,""],providers_delete:[2,1,1,""],providers_info:[2,1,1,""],providers_list:[2,1,1,""],providers_push:[2,1,1,""],providers_save:[2,1,1,""],providers_show:[2,1,1,""],providers_template:[2,1,1,""]},"composer.cli.sources":{sources_add:[2,1,1,""],sources_cmd:[2,1,1,""],sources_delete:[2,1,1,""],sources_info:[2,1,1,""],sources_list:[2,1,1,""]},"composer.cli.status":{status_cmd:[2,1,1,""]},"composer.cli.upload":{upload_cancel:[2,1,1,""],upload_cmd:[2,1,1,""],upload_delete:[2,1,1,""],upload_info:[2,1,1,""],upload_list:[2,1,1,""],upload_log:[2,1,1,""],upload_reset:[2,1,1,""],upload_start:[2,1,1,""]},"composer.cli.utilities":{argify:[2,1,1,""],frozen_toml_filename:[2,1,1,""],get_arg:[2,1,1,""],handle_api_result:[2,1,1,""],packageNEVRA:[2,1,1,""],toml_filename:[2,1,1,""]},"composer.http_client":{api_url:[0,1,1,""],append_query:[0,1,1,""],delete_url_json:[0,1,1,""],download_file:[0,1,1,""],get_filename:[0,1,1,""],get_url_json:[0,1,1,""],get_url_json_unlimited:[0,1,1,""],get_url_raw:[0,1,1,""],post_url:[0,1,1,""],post_url_json:[0,1,1,""],post_url_toml:[0,1,1,""]},"composer.unix_socket":{UnixHTTPConnection:[0,2,1,""],UnixHTTPConnectionPool:[0,2,1,""]},"composer.unix_socket.UnixHTTPConnection":{connect:[0,3,1,""]},"lifted.config":{configure:[5,1,1,""]},"lifted.providers":{delete_profile:[5,1,1,""],list_providers:[5,1,1,""],load_profiles:[5,1,1,""],load_settings:[5,1,1,""],resolve_playbook_path:[5,1,1,""],resolve_provider:[5,1,1,""],save_settings:[5,1,1,""],validate_settings:[5,1,1,""]},"lifted.queue":{cancel_upload:[5,1,1,""],create_upload:[5,1,1,""],delete_upload:[5,1,1,""],get_all_uploads:[5,1,1,""],get_upload:[5,1,1,""],get_uploads:[5,1,1,""],ready_upload:[5,1,1,""],reset_upload:[5,1,1,""],start_upload_monitor:[5,1,1,""]},"lifted.upload":{Upload:[5,2,1,""]},"lifted.upload.Upload":{cancel:[5,3,1,""],execute:[5,3,1,""],is_cancellable:[5,3,1,""],ready:[5,3,1,""],reset:[5,3,1,""],serializable:[5,3,1,""],set_status:[5,3,1,""],summary:[5,3,1,""]},"pylorax.ArchData":{bcj_arch:[12,4,1,""],lib64_arches:[12,4,1,""]},"pylorax.Lorax":{configure:[12,3,1,""],init_file_logging:[12,3,1,""],init_stream_logging:[12,3,1,""],run:[12,3,1,""],templatedir:[12,3,1,""]},"pylorax.api":{bisect:[13,0,0,"-"],checkparams:[13,0,0,"-"],cmdline:[13,0,0,"-"],compose:[13,0,0,"-"],config:[13,0,0,"-"],dnfbase:[13,0,0,"-"],errors:[13,0,0,"-"],flask_blueprint:[13,0,0,"-"],gitrpm:[13,0,0,"-"],projects:[13,0,0,"-"],queue:[13,0,0,"-"],recipes:[13,0,0,"-"],regexes:[13,0,0,"-"],server:[13,0,0,"-"],timestamp:[13,0,0,"-"],toml:[13,0,0,"-"],utils:[13,0,0,"-"],v0:[13,0,0,"-"],v1:[13,0,0,"-"],workspace:[13,0,0,"-"]},"pylorax.api.bisect":{insort_left:[13,1,1,""]},"pylorax.api.checkparams":{checkparams:[13,1,1,""]},"pylorax.api.cmdline":{lorax_composer_parser:[13,1,1,""]},"pylorax.api.compose":{add_customizations:[13,1,1,""],bootloader_append:[13,1,1,""],compose_args:[13,1,1,""],compose_types:[13,1,1,""],customize_ks_template:[13,1,1,""],firewall_cmd:[13,1,1,""],get_default_services:[13,1,1,""],get_extra_pkgs:[13,1,1,""],get_firewall_settings:[13,1,1,""],get_kernel_append:[13,1,1,""],get_keyboard_layout:[13,1,1,""],get_languages:[13,1,1,""],get_services:[13,1,1,""],get_timezone_settings:[13,1,1,""],keyboard_cmd:[13,1,1,""],lang_cmd:[13,1,1,""],move_compose_results:[13,1,1,""],repo_to_ks:[13,1,1,""],services_cmd:[13,1,1,""],start_build:[13,1,1,""],test_templates:[13,1,1,""],timezone_cmd:[13,1,1,""],write_ks_group:[13,1,1,""],write_ks_root:[13,1,1,""],write_ks_user:[13,1,1,""]},"pylorax.api.config":{ComposerConfig:[13,2,1,""],configure:[13,1,1,""],make_dnf_dirs:[13,1,1,""],make_owned_dir:[13,1,1,""],make_queue_dirs:[13,1,1,""]},"pylorax.api.config.ComposerConfig":{get_default:[13,3,1,""]},"pylorax.api.dnfbase":{DNFLock:[13,2,1,""],get_base_object:[13,1,1,""]},"pylorax.api.dnfbase.DNFLock":{lock:[13,3,1,""],lock_check:[13,3,1,""]},"pylorax.api.flask_blueprint":{BlueprintSetupStateSkip:[13,2,1,""],BlueprintSkip:[13,2,1,""]},"pylorax.api.flask_blueprint.BlueprintSetupStateSkip":{add_url_rule:[13,3,1,""]},"pylorax.api.flask_blueprint.BlueprintSkip":{make_setup_state:[13,3,1,""]},"pylorax.api.gitrpm":{GitArchiveTarball:[13,2,1,""],GitRpmBuild:[13,2,1,""],create_gitrpm_repo:[13,1,1,""],get_repo_description:[13,1,1,""],make_git_rpm:[13,1,1,""]},"pylorax.api.gitrpm.GitArchiveTarball":{write_file:[13,3,1,""]},"pylorax.api.gitrpm.GitRpmBuild":{add_git_tarball:[13,3,1,""],check:[13,3,1,""],clean:[13,3,1,""],cleanup_tmpdir:[13,3,1,""],get_base_dir:[13,3,1,""]},"pylorax.api.projects":{ProjectsError:[13,5,1,""],api_changelog:[13,1,1,""],api_time:[13,1,1,""],delete_repo_source:[13,1,1,""],dep_evra:[13,1,1,""],dep_nevra:[13,1,1,""],dnf_repo_to_file_repo:[13,1,1,""],estimate_size:[13,1,1,""],get_repo_sources:[13,1,1,""],get_source_ids:[13,1,1,""],modules_info:[13,1,1,""],modules_list:[13,1,1,""],new_repo_source:[13,1,1,""],pkg_to_build:[13,1,1,""],pkg_to_dep:[13,1,1,""],pkg_to_project:[13,1,1,""],pkg_to_project_info:[13,1,1,""],proj_to_module:[13,1,1,""],projects_depsolve:[13,1,1,""],projects_depsolve_with_size:[13,1,1,""],projects_info:[13,1,1,""],projects_list:[13,1,1,""],repo_to_source:[13,1,1,""],source_to_repo:[13,1,1,""],source_to_repodict:[13,1,1,""]},"pylorax.api.queue":{build_status:[13,1,1,""],check_queues:[13,1,1,""],compose_detail:[13,1,1,""],get_compose_type:[13,1,1,""],get_image_name:[13,1,1,""],make_compose:[13,1,1,""],monitor:[13,1,1,""],queue_status:[13,1,1,""],start_queue_monitor:[13,1,1,""],uuid_add_upload:[13,1,1,""],uuid_cancel:[13,1,1,""],uuid_delete:[13,1,1,""],uuid_get_uploads:[13,1,1,""],uuid_image:[13,1,1,""],uuid_info:[13,1,1,""],uuid_log:[13,1,1,""],uuid_ready_upload:[13,1,1,""],uuid_remove_upload:[13,1,1,""],uuid_schedule_upload:[13,1,1,""],uuid_status:[13,1,1,""],uuid_tar:[13,1,1,""]},"pylorax.api.recipes":{CommitDetails:[13,2,1,""],CommitTimeValError:[13,5,1,""],NewRecipeGit:[13,1,1,""],Recipe:[13,2,1,""],RecipeError:[13,5,1,""],RecipeFileError:[13,5,1,""],RecipeGit:[13,2,1,""],RecipeGroup:[13,2,1,""],RecipeModule:[13,2,1,""],RecipePackage:[13,2,1,""],check_list_case:[13,1,1,""],check_recipe_dict:[13,1,1,""],check_required_list:[13,1,1,""],commit_recipe:[13,1,1,""],commit_recipe_directory:[13,1,1,""],commit_recipe_file:[13,1,1,""],customizations_diff:[13,1,1,""],delete_file:[13,1,1,""],delete_recipe:[13,1,1,""],diff_lists:[13,1,1,""],find_commit_tag:[13,1,1,""],find_field_value:[13,1,1,""],find_name:[13,1,1,""],find_recipe_obj:[13,1,1,""],get_commit_details:[13,1,1,""],get_revision_from_tag:[13,1,1,""],gfile:[13,1,1,""],head_commit:[13,1,1,""],is_commit_tag:[13,1,1,""],is_parent_diff:[13,1,1,""],list_branch_files:[13,1,1,""],list_commit_files:[13,1,1,""],list_commits:[13,1,1,""],open_or_create_repo:[13,1,1,""],prepare_commit:[13,1,1,""],read_commit:[13,1,1,""],read_commit_spec:[13,1,1,""],read_recipe_and_id:[13,1,1,""],read_recipe_commit:[13,1,1,""],recipe_diff:[13,1,1,""],recipe_filename:[13,1,1,""],recipe_from_dict:[13,1,1,""],recipe_from_file:[13,1,1,""],recipe_from_toml:[13,1,1,""],repo_file_exists:[13,1,1,""],revert_file:[13,1,1,""],revert_recipe:[13,1,1,""],tag_file_commit:[13,1,1,""],tag_recipe_commit:[13,1,1,""],write_commit:[13,1,1,""]},"pylorax.api.recipes.Recipe":{bump_version:[13,3,1,""],filename:[13,3,1,""],freeze:[13,3,1,""],group_names:[13,3,1,""],module_names:[13,3,1,""],module_nver:[13,3,1,""],package_names:[13,3,1,""],package_nver:[13,3,1,""],toml:[13,3,1,""]},"pylorax.api.server":{GitLock:[13,2,1,""]},"pylorax.api.server.GitLock":{dir:[13,4,1,""],lock:[13,4,1,""],repo:[13,4,1,""]},"pylorax.api.timestamp":{timestamp_dict:[13,1,1,""],write_timestamp:[13,1,1,""]},"pylorax.api.toml":{TomlError:[13,5,1,""],dump:[13,1,1,""],dumps:[13,1,1,""],load:[13,1,1,""],loads:[13,1,1,""]},"pylorax.api.utils":{blueprint_exists:[13,1,1,""],take_limits:[13,1,1,""]},"pylorax.api.v0":{v0_blueprints_changes:[13,1,1,""],v0_blueprints_delete:[13,1,1,""],v0_blueprints_delete_workspace:[13,1,1,""],v0_blueprints_depsolve:[13,1,1,""],v0_blueprints_diff:[13,1,1,""],v0_blueprints_freeze:[13,1,1,""],v0_blueprints_info:[13,1,1,""],v0_blueprints_list:[13,1,1,""],v0_blueprints_new:[13,1,1,""],v0_blueprints_tag:[13,1,1,""],v0_blueprints_undo:[13,1,1,""],v0_blueprints_workspace:[13,1,1,""],v0_compose_cancel:[13,1,1,""],v0_compose_delete:[13,1,1,""],v0_compose_failed:[13,1,1,""],v0_compose_finished:[13,1,1,""],v0_compose_image:[13,1,1,""],v0_compose_info:[13,1,1,""],v0_compose_log_tail:[13,1,1,""],v0_compose_logs:[13,1,1,""],v0_compose_metadata:[13,1,1,""],v0_compose_queue:[13,1,1,""],v0_compose_results:[13,1,1,""],v0_compose_start:[13,1,1,""],v0_compose_status:[13,1,1,""],v0_compose_types:[13,1,1,""],v0_modules_info:[13,1,1,""],v0_modules_list:[13,1,1,""],v0_projects_depsolve:[13,1,1,""],v0_projects_info:[13,1,1,""],v0_projects_list:[13,1,1,""],v0_projects_source_delete:[13,1,1,""],v0_projects_source_info:[13,1,1,""],v0_projects_source_list:[13,1,1,""],v0_projects_source_new:[13,1,1,""]},"pylorax.api.v1":{v1_compose_failed:[13,1,1,""],v1_compose_finished:[13,1,1,""],v1_compose_info:[13,1,1,""],v1_compose_queue:[13,1,1,""],v1_compose_start:[13,1,1,""],v1_compose_status:[13,1,1,""],v1_compose_uploads_delete:[13,1,1,""],v1_compose_uploads_schedule:[13,1,1,""],v1_projects_source_info:[13,1,1,""],v1_projects_source_new:[13,1,1,""],v1_providers_delete:[13,1,1,""],v1_providers_save:[13,1,1,""],v1_upload_cancel:[13,1,1,""],v1_upload_info:[13,1,1,""],v1_upload_log:[13,1,1,""],v1_upload_providers:[13,1,1,""],v1_upload_reset:[13,1,1,""]},"pylorax.api.workspace":{workspace_delete:[13,1,1,""],workspace_dir:[13,1,1,""],workspace_exists:[13,1,1,""],workspace_filename:[13,1,1,""],workspace_read:[13,1,1,""],workspace_write:[13,1,1,""]},"pylorax.base":{BaseLoraxClass:[12,2,1,""],DataHolder:[12,2,1,""]},"pylorax.base.BaseLoraxClass":{pcritical:[12,3,1,""],pdebug:[12,3,1,""],perror:[12,3,1,""],pinfo:[12,3,1,""],pwarning:[12,3,1,""]},"pylorax.base.DataHolder":{copy:[12,3,1,""]},"pylorax.buildstamp":{BuildStamp:[12,2,1,""]},"pylorax.buildstamp.BuildStamp":{write:[12,3,1,""]},"pylorax.cmdline":{lmc_parser:[12,1,1,""],lorax_parser:[12,1,1,""]},"pylorax.creator":{FakeDNF:[12,2,1,""],calculate_disk_size:[12,1,1,""],check_kickstart:[12,1,1,""],create_pxe_config:[12,1,1,""],dracut_args:[12,1,1,""],find_ostree_root:[12,1,1,""],get_arch:[12,1,1,""],is_image_mounted:[12,1,1,""],make_appliance:[12,1,1,""],make_image:[12,1,1,""],make_live_images:[12,1,1,""],make_livecd:[12,1,1,""],make_runtime:[12,1,1,""],mount_boot_part_over_root:[12,1,1,""],rebuild_initrds_for_live:[12,1,1,""],run_creator:[12,1,1,""],squashfs_args:[12,1,1,""]},"pylorax.creator.FakeDNF":{reset:[12,3,1,""]},"pylorax.decorators":{singleton:[12,1,1,""]},"pylorax.discinfo":{DiscInfo:[12,2,1,""]},"pylorax.discinfo.DiscInfo":{write:[12,3,1,""]},"pylorax.dnfbase":{get_dnf_base_object:[12,1,1,""]},"pylorax.dnfhelper":{LoraxDownloadCallback:[12,2,1,""],LoraxRpmCallback:[12,2,1,""]},"pylorax.dnfhelper.LoraxDownloadCallback":{end:[12,3,1,""],progress:[12,3,1,""],start:[12,3,1,""]},"pylorax.dnfhelper.LoraxRpmCallback":{error:[12,3,1,""],progress:[12,3,1,""]},"pylorax.executils":{ExecProduct:[12,2,1,""],augmentEnv:[12,1,1,""],execReadlines:[12,1,1,""],execWithCapture:[12,1,1,""],execWithRedirect:[12,1,1,""],runcmd:[12,1,1,""],runcmd_output:[12,1,1,""],setenv:[12,1,1,""],startProgram:[12,1,1,""]},"pylorax.imgutils":{DMDev:[12,2,1,""],LoopDev:[12,2,1,""],Mount:[12,2,1,""],PartitionMount:[12,2,1,""],compress:[12,1,1,""],copytree:[12,1,1,""],default_image_name:[12,1,1,""],dm_attach:[12,1,1,""],dm_detach:[12,1,1,""],do_grafts:[12,1,1,""],estimate_size:[12,1,1,""],get_loop_name:[12,1,1,""],kpartx_disk_img:[12,1,1,""],loop_attach:[12,1,1,""],loop_detach:[12,1,1,""],loop_waitfor:[12,1,1,""],mkbtrfsimg:[12,1,1,""],mkcpio:[12,1,1,""],mkdosimg:[12,1,1,""],mkext4img:[12,1,1,""],mkfsimage:[12,1,1,""],mkfsimage_from_disk:[12,1,1,""],mkhfsimg:[12,1,1,""],mkqcow2:[12,1,1,""],mkqemu_img:[12,1,1,""],mkrootfsimg:[12,1,1,""],mksparse:[12,1,1,""],mksquashfs:[12,1,1,""],mktar:[12,1,1,""],mount:[12,1,1,""],round_to_blocks:[12,1,1,""],umount:[12,1,1,""]},"pylorax.installer":{InstallError:[12,5,1,""],QEMUInstall:[12,2,1,""],anaconda_cleanup:[12,1,1,""],append_initrd:[12,1,1,""],create_vagrant_metadata:[12,1,1,""],find_free_port:[12,1,1,""],novirt_cancel_check:[12,1,1,""],novirt_install:[12,1,1,""],update_vagrant_metadata:[12,1,1,""],virt_install:[12,1,1,""]},"pylorax.installer.QEMUInstall":{QEMU_CMDS:[12,4,1,""]},"pylorax.ltmpl":{LiveTemplateRunner:[12,2,1,""],LoraxTemplate:[12,2,1,""],LoraxTemplateRunner:[12,2,1,""],TemplateRunner:[12,2,1,""],brace_expand:[12,1,1,""],rexists:[12,1,1,""],rglob:[12,1,1,""],split_and_expand:[12,1,1,""]},"pylorax.ltmpl.LiveTemplateRunner":{installpkg:[12,3,1,""]},"pylorax.ltmpl.LoraxTemplate":{parse:[12,3,1,""]},"pylorax.ltmpl.LoraxTemplateRunner":{append:[12,3,1,""],chmod:[12,3,1,""],copy:[12,3,1,""],createaddrsize:[12,3,1,""],hardlink:[12,3,1,""],install:[12,3,1,""],installimg:[12,3,1,""],installinitrd:[12,3,1,""],installkernel:[12,3,1,""],installpkg:[12,3,1,""],installupgradeinitrd:[12,3,1,""],log:[12,3,1,""],mkdir:[12,3,1,""],move:[12,3,1,""],remove:[12,3,1,""],removefrom:[12,3,1,""],removekmod:[12,3,1,""],removepkg:[12,3,1,""],replace:[12,3,1,""],run_pkg_transaction:[12,3,1,""],runcmd:[12,3,1,""],symlink:[12,3,1,""],systemctl:[12,3,1,""],treeinfo:[12,3,1,""]},"pylorax.ltmpl.TemplateRunner":{run:[12,3,1,""]},"pylorax.monitor":{LogMonitor:[12,2,1,""],LogRequestHandler:[12,2,1,""],LogServer:[12,2,1,""]},"pylorax.monitor.LogMonitor":{shutdown:[12,3,1,""]},"pylorax.monitor.LogRequestHandler":{finish:[12,3,1,""],handle:[12,3,1,""],iserror:[12,3,1,""],re_tests:[12,4,1,""],setup:[12,3,1,""],simple_tests:[12,4,1,""]},"pylorax.monitor.LogServer":{log_check:[12,3,1,""],timeout:[12,4,1,""]},"pylorax.mount":{IsoMountpoint:[12,2,1,""]},"pylorax.mount.IsoMountpoint":{get_iso_label:[12,3,1,""],umount:[12,3,1,""]},"pylorax.sysutils":{chmod_:[12,1,1,""],chown_:[12,1,1,""],joinpaths:[12,1,1,""],linktree:[12,1,1,""],remove:[12,1,1,""],replace:[12,1,1,""],touch:[12,1,1,""]},"pylorax.treebuilder":{RuntimeBuilder:[12,2,1,""],TreeBuilder:[12,2,1,""],findkernels:[12,1,1,""],generate_module_info:[12,1,1,""],string_lower:[12,1,1,""],udev_escape:[12,1,1,""]},"pylorax.treebuilder.RuntimeBuilder":{cleanup:[12,3,1,""],create_ext4_runtime:[12,3,1,""],create_squashfs_runtime:[12,3,1,""],finished:[12,3,1,""],generate_module_data:[12,3,1,""],install:[12,3,1,""],postinstall:[12,3,1,""],verify:[12,3,1,""],writepkglists:[12,3,1,""],writepkgsizes:[12,3,1,""]},"pylorax.treebuilder.TreeBuilder":{build:[12,3,1,""],copy_dracut_hooks:[12,3,1,""],dracut_hooks_path:[12,3,1,""],implantisomd5:[12,3,1,""],kernels:[12,3,1,""],rebuild_initrds:[12,3,1,""]},"pylorax.treeinfo":{TreeInfo:[12,2,1,""]},"pylorax.treeinfo.TreeInfo":{add_section:[12,3,1,""],write:[12,3,1,""]},composer:{cli:[2,0,0,"-"],http_client:[0,0,0,"-"],unix_socket:[0,0,0,"-"]},lifted:{config:[5,0,0,"-"],providers:[5,0,0,"-"],queue:[5,0,0,"-"],upload:[5,0,0,"-"]},pylorax:{ArchData:[12,2,1,""],Lorax:[12,2,1,""],api:[13,0,0,"-"],base:[12,0,0,"-"],buildstamp:[12,0,0,"-"],cmdline:[12,0,0,"-"],creator:[12,0,0,"-"],decorators:[12,0,0,"-"],discinfo:[12,0,0,"-"],dnfbase:[12,0,0,"-"],dnfhelper:[12,0,0,"-"],executils:[12,0,0,"-"],find_templates:[12,1,1,""],get_buildarch:[12,1,1,""],imgutils:[12,0,0,"-"],installer:[12,0,0,"-"],log_selinux_state:[12,1,1,""],ltmpl:[12,0,0,"-"],monitor:[12,0,0,"-"],mount:[12,0,0,"-"],output:[12,0,0,"-"],setup_logging:[12,1,1,""],sysutils:[12,0,0,"-"],treebuilder:[12,0,0,"-"],treeinfo:[12,0,0,"-"]}},objnames:{"0":["py","module","Python module"],"1":["py","function","Python function"],"2":["py","class","Python class"],"3":["py","method","Python method"],"4":["py","attribute","Python attribute"],"5":["py","exception","Python exception"]},objtypes:{"0":"py:module","1":"py:function","2":"py:class","3":"py:method","4":"py:attribute","5":"py:exception"},terms:{"0034983":13,"0077":12,"01t08":13,"03374adbf080fe34f5c6c29f2e49cc2b86958bf2":13,"03397f8d":13,"037a3d56":13,"069004":13,"06e8":13,"08t00":13,"0ad":13,"0e08ecbb708675bfabc82952599a1712a843779d":13,"0fa2":13,"0instal":13,"1003145":13,"1024":[1,2,12,13],"10t23":13,"1130":8,"11t00":13,"11t01":13,"1200":8,"1234567":13,"127":[6,12],"13z":13,"140629395244800":13,"14526ba628bb":13,"1517351003":13,"1517359234":13,"1517362289":13,"1517362633":13,"1517362647":13,"1517362659":13,"1517363442":13,"1517363451":13,"1517363500":13,"1517523249":13,"1517523255":13,"1517523644":13,"1517523689":13,"154":13,"155":13,"1565620940":13,"1568150660":13,"188399":13,"18bb14679fc7":13,"1kb":2,"2017":13,"2048":[6,12,13],"21600":13,"21770":13,"21898dfd":13,"222":13,"223":13,"232":6,"2384307":13,"23t00":13,"2551234":13,"256":12,"28z":13,"29b492f26ed35d80800b536623bafc51e2f0eff2":13,"2b4174b3614b":13,"2ping":13,"300":0,"30z":13,"3128":6,"325324":13,"3700mib":12,"3726a1093fd0":13,"397f":13,"3e11eb87a63d289662cba4b1804a0947a6843379":13,"3rn8evie2t50lmvybyihtgvrhcaecmeck31l":8,"400":13,"4096":12,"41ef9c3e4b73":13,"4279":13,"42fc":13,"43e9":13,"44c0":13,"45502a6d":13,"4570868":13,"45e380f39894":13,"4600":13,"467":13,"47z":13,"4825":13,"48a5":13,"48ec":13,"4a23":13,"4af9":13,"4b70":13,"4b8a":13,"4c68":13,"4c9f":13,"4cdb":13,"4e22":13,"500":6,"512":6,"523b":13,"524401":13,"52z":13,"5348":13,"5623411":13,"56z":13,"572eb0d0":13,"5900":12,"5999":12,"6080":12,"6144":13,"61b799739ce8":13,"653621":13,"6c8d38e3b211":13,"6d292bd0":13,"7078e521a54b12eae31c3fd028680da7a0815a4d":13,"70b84195":13,"7193348":13,"745712b2":13,"782":13,"784":13,"7965999":13,"7f12d0129e65":13,"7f16":13,"8001345":13,"8014":13,"8123":13,"8210032":13,"8230415":13,"870f":13,"8c8435ef":13,"8d7d":13,"9022":13,"912":13,"913":13,"9301329":13,"9314211":13,"9394":13,"9666":13,"96db":13,"9751132":13,"9817":13,"9864314":13,"9935":13,"99anaconda":12,"9ac9":13,"9bf1":13,"9c81":13,"9d26":13,"9d9d":13,"boolean":5,"byte":13,"case":[8,13],"catch":[6,12],"char":12,"class":[0,5,11,12,13],"default":[1,5,8,9,12,13],"final":[1,4,6,7,8,11,12,13],"function":[2,5,8,12,13],"import":[6,12,13],"int":[2,12,13],"long":1,"new":[0,1,2,4,5,6,7,8,9,12],"null":[6,13],"public":[6,8],"return":[0,1,2,5,8,12,13],"short":[8,13],"switch":6,"true":[0,2,5,6,7,8,12,13],"try":[1,6,12,13],"var":[5,6,7,8,12,13],"while":[8,11,12,13],ADDING:12,Adding:12,And:6,But:[6,8],For:[0,1,6,8,12,13],Its:[4,7],NOT:13,Not:12,One:[6,8],RTS:13,THE:13,The:[0,1,2,4,5,6,8,9,11,12,13],Then:9,There:[1,6,8,9,12,13],These:[1,6,7,8,11,13],Use:[6,7,12,13],Used:[6,12,13],Uses:13,Using:[7,13],Will:12,Yes:12,__dict__:5,__init__:0,_io:12,_map:8,a215:13,a2ef832e6b1a:13,a697ca405cdf:13,a8ef:13,aarch64:[7,11,12],abbrevi:6,abl:[7,8,9],abort:6,about:[1,2,5,6,13],abov:[1,6],absolut:12,accept:8,access:[1,6,8,13],accomplish:6,account:[8,12],acff:13,acl:[12,13],action:12,activ:[6,8],actual:[1,12,13],ad52:13,add2636e7459:13,add:[0,1,2,5,6,7,9,11,12,13],add_arch_templ:[7,12],add_arch_template_var:[7,12],add_arg:12,add_custom:13,add_git_tarbal:13,add_new_repo:13,add_path:9,add_sect:12,add_templ:[7,12],add_template_var:[7,12],add_url_rul:13,added:[6,8,9,12,13],adding:[8,12],addit:[1,2,6,7,8,12,13],addon:13,addr:12,addrsiz:12,admin:8,administr:8,ae1bf7e3:13,af92:13,afford:6,after:[1,6,7,12,13],again:[1,2,5,13],against:[5,6],ain:13,alia:13,alibaba:[1,13],align:6,all:[0,1,2,4,5,6,7,8,11,12,13],allbut:[7,12],alloc:6,allow:[6,7,8],allow_no_valu:13,almost:4,along:[7,13],alreadi:[1,8,12,13],also:[1,5,6,7,8,9,12,13],alwai:[6,8,13],amazon:6,america:8,ami:[1,8],amount:8,anaconda:[1,4,7,8,9,11,12,13],anaconda_arg:[6,13],anaconda_cleanup:12,anaconfigurationthread:13,ancient:13,ani:[0,1,2,5,6,7,8,9,12,13],anoth:[1,6,7,12],ansibl:1,anyth:[1,11,13],anywher:12,api:[0,1,2,8,10,12],api_changelog:13,api_tim:13,api_url:0,api_vers:[0,2],apiv:1,app:[6,13],app_fil:6,app_nam:6,app_templ:6,appear:12,append:[0,2,6,7,8,12,13],append_initrd:12,append_queri:0,appli:[1,12,13],applianc:12,applic:[8,13],appropri:[6,12],arbitrari:[7,8],arch:[2,4,6,7,12,13],archdata:12,architectur:[4,6,7,9,12],archiv:[6,8,11,12,13],aren:[7,13],arg:[1,2,6,7,12,13],argifi:2,argpars:[2,12],argtyp:2,argument:[0,2,12,13],argumentpars:[2,12,13],argv:12,arm:[6,12],armhfp:12,armplatform:[6,13],around:6,artifact:[6,13],assembl:13,associ:[1,2,5,12,13],assum:[12,13],atla:13,attach:12,attempt:[4,5,12,13],attr:13,attribut:[6,13],audit:13,augmentenv:12,authent:[1,13],author:[1,6,7,8,9,13],authorized_kei:8,automat:[7,8,12,13],avahi:13,avail:[1,2,5,6,8,9,13],awar:8,aws:1,aws_access_kei:1,aws_bucket:1,aws_region:1,aws_secret_kei:1,azur:[5,13],b067:13,b36e:13,b421:13,b6218e8f:13,b637c411:13,back:[1,7,12,13],backend:2,backup:[12,13],bare:[6,13],base:[0,5,6,7,8,10,13],basearch:[12,13],baseimag:8,baseloraxclass:12,basenam:12,baserequesthandl:12,basesystem:13,baseurl:[6,8,9,13],bash:[4,6,8,13],basic:[1,7],bb1d:13,bcj_arch:12,bcl:[1,6,7,8,9],bd31:13,bdc:8,bec7:13,becaus:[6,7,8,13],becom:[6,8],been:[6,9,12,13],befor:[3,6,7,8,12,13],behavior:13,behind:[8,12],being:[6,7,8,13],below:[6,7,13],best:[6,7,8,13],better:12,between:[1,2,6,7,8,12,13],big:12,bin:[6,8,12],binari:[6,12],binary_output:12,bind:6,bind_mount_opt:6,bio:6,bisect:[10,12],bit:8,blob:13,block:[7,8,12,13],block_siz:13,blocksiz:12,blog:8,blueprint:[0,9,10,13],blueprint_exist:13,blueprint_nam:[2,13],blueprints_chang:2,blueprints_cmd:2,blueprints_delet:2,blueprints_depsolv:2,blueprints_diff:2,blueprints_freez:2,blueprints_freeze_sav:2,blueprints_freeze_show:2,blueprints_list:2,blueprints_push:2,blueprints_sav:2,blueprints_show:2,blueprints_tag:2,blueprints_undo:2,blueprints_workspac:2,blueprintsetupst:13,blueprintsetupstateskip:13,blueprintskip:13,bodi:[0,13],bool:[2,5,12,13],boot:[1,4,7,8,11,12,13],boot_uefi:12,bootabl:[6,7],bootdir:12,bootload:[6,8,9,13],bootloader_append:13,bootproto:6,both:[1,6,8,13],bound:13,boundari:13,box:6,brace:12,brace_expand:12,branch:[6,8,13],brian:[1,6,7,8,9],brianlan:13,browser:8,bucket:1,bug:[6,7,8],bugurl:[7,12],bugzilla:6,build:[2,4,6,7,8,11,12,13],build_config_ref:13,build_env_ref:13,build_id:13,build_statu:13,build_tim:13,buildarch:[7,12],builder:[6,13],buildinstal:4,buildsi:6,buildstamp:10,built:[1,7,12,13],builtin:12,bump:[8,13],bump_vers:13,bunch:12,bundl:6,bzip2:[6,12],c30b7d80:13,c75d5d62:13,c98350c89996:13,cach:[6,7,8,12],cachedir:[7,12],calcul:12,calculate_disk_s:12,call:[4,5,6,12,13],callback:[5,12,13],calledprocesserror:12,caller:13,can:[1,2,5,6,7,8,9,11,12,13],cancel:[1,2,5,6,12,13],cancel_func:12,cancel_upload:5,cannot:[0,6,7,8,13],captur:12,care:[9,12,13],cat:6,categor:8,caught:[6,13],caus:[1,7,8,12],cdboot:8,cdlabel:12,cdrom:9,cee5f4c20fc33ea4d54bfecf56f4ad41ad15f4f3:13,central:4,cert:12,certif:[7,8,13],cfg:[12,13],chang:[1,2,6,7,8,9,12,13],changelog:[1,13],charact:[8,12],check:[2,5,8,9,12,13],check_gpg:[8,13],check_kickstart:12,check_list_cas:13,check_queu:13,check_recipe_dict:13,check_required_list:13,check_ssl:[8,13],checkparam:[10,12],checksum:[6,9],checksum_typ:6,child:12,chmod:[7,12],chmod_:12,cho2:8,choic:1,choos:6,chosen:[6,12,13],chown_:12,chronyd:8,chroot:[6,7,11,12],chroot_setup_cmd:6,chvt:6,cisco:13,clean:[4,6,8,12,13],cleanup:[6,12,13],cleanup_tmpdir:13,clear:[4,8,13],clearpart:6,cli:[0,3,8,10,13],client:[0,6,13],client_address:12,client_id:13,clone:[8,13],close:12,cloud:[5,6,8,13],cls:12,cmd:[8,12],cmdline:[0,10],cmdlist:12,cockpit:8,code:[7,8,12,13],collect:13,com:[1,6,7,8,9,13],combin:[2,6,13],come:13,comma:[2,12,13],command:[0,1,2,4,6,7,8,9,11,12,13],commandlin:[1,8,12],comment_prefix:13,commit:[1,2,8,13],commit_id:13,commit_recip:13,commit_recipe_directori:13,commit_recipe_fil:13,commitdetail:13,committimevalerror:13,common:[6,7],commonli:8,commun:[0,1,2,8],comoposit:13,compar:13,comparison:13,compat:[1,8],complet:[4,8,12,13],compon:6,compos:[3,5,9,10,12],compose_arg:[8,13],compose_cancel:2,compose_cmd:2,compose_delet:2,compose_detail:13,compose_imag:2,compose_info:2,compose_list:2,compose_log:2,compose_metadata:2,compose_ostre:2,compose_result:2,compose_start:2,compose_statu:[2,13],compose_typ:[2,8,13],compose_uuid:13,composer_cli_pars:2,composerconfig:[5,13],composerpars:13,composit:13,compress:[6,11,12,13],compress_arg:[6,13],compressarg:12,compressopt:12,comput:12,conf:[4,5,6,7,8,12,13],conf_fil:[12,13],config:[6,7,8,10,12],config_opt:6,configfil:7,configpars:13,configur:[4,5,6,7,8,9,12,13],conflict:[7,8],connect:[0,9],connectionpool:0,consist:[1,4],consol:8,construct:[8,12],constructor:13,contain:[4,7,8,9,11,12,13],content:[3,7,8,9,10,11],context:12,continu:[2,12],control:[4,8,12,13],convent:6,convers:1,convert:[1,2,6,8,12,13],copi:[1,4,6,7,8,9,11,12,13],copy_dracut_hook:12,copyin:6,copytre:12,core:6,correct:[1,2,4,6,8,12,13],correctli:[6,8,12,13],correspond:[7,12],corrupt:[5,9],could:[5,6,8],couldn:5,count:13,coupl:[1,6],cpio:12,cpu:12,crash:12,creat:[1,4,5,7,8,11,12,13],create_ext4_runtim:12,create_gitrpm_repo:13,create_pxe_config:12,create_squashfs_runtim:12,create_upload:5,create_vagrant_metadata:12,createaddrs:12,createrepo:6,createrepo_c:[9,13],creation:[4,9,11,12,13],creation_tim:[5,13],creator:[3,8,9,10,13],credenti:1,cross:13,current:[1,4,5,6,8,12,13],custom:[4,6,9,11,13],customizations_diff:13,customize_ks_templ:13,cwd:0,d6bd:13,data:[0,4,6,12,13],datahold:[12,13],dbo:[12,13],debug:[8,9,12],decod:[12,13],decor:10,dedic:5,dee:13,default_image_nam:12,default_sect:13,defin:[5,6,8,13],delai:[8,12],delet:[0,1,2,5,6,7,8,12,13],delete_fil:13,delete_profil:5,delete_recip:13,delete_repo_sourc:13,delete_upload:5,delete_url_json:0,delimit:13,denial:[6,8],dep:13,dep_evra:13,dep_nevra:13,depend:[1,2,6,7,8,9,11,13],deploy:[8,12,13],depmod:12,deprec:8,depsolv:[1,2,8,13],describ:[1,6,8,13],descript:[1,6,8,12,13],deseri:5,desir:13,desktop:6,dest:[12,13],destdir:13,destfil:12,destin:[7,8,12,13],detach:12,detail:[1,2,8,13],detect:[6,12],dev:[6,7,12],devel:6,develop:[6,8,13],devic:[6,7,12],devicemapp:12,dhcp:[6,8],dialog:6,dict:[0,2,5,12,13],dict_nam:2,dict_typ:13,dictionari:13,didn:6,died:6,diff:[1,2,13],diff_list:13,differ:[1,2,5,6,8,12,13],difficult:13,dir:[6,7,12,13],direcori:12,direct:13,directli:[1,2,6,8,13],directori:[1,5,6,7,8,9,11,12,13],dirinstall_path:12,disabl:[7,8,12,13],disablerepo:[7,12],disassoci:13,discinfo:[7,10],disk:[1,9,12,13],disk_imag:6,disk_img:12,disk_info:6,disk_siz:12,diskimag:12,dispatch:2,displai:[1,2,5,6,8,13],disposit:0,distinct:13,distribut:[7,8],dm_attach:12,dm_detach:12,dmdev:12,dmsetup:12,dnf:[7,8,12,13],dnf_conf:13,dnf_obj:12,dnf_repo_to_file_repo:13,dnfbase:10,dnfhelper:10,dnflock:13,dnfplugin:[7,12],do_graft:12,doc:[6,8,13],document:[6,7,8,9],doe:[2,6,7,8,9,12,13],doesn:[1,2,6,7,8,12,13],doing:[6,8,13],domacboot:12,domain:8,don:[5,6,9,12,13],done:[1,12,13],doupgrad:12,down:13,download:[0,2,6,7,12,13],download_fil:0,downloadprogress:12,dracut:12,dracut_arg:[6,7,12],dracut_conf:[6,7],dracut_default:12,dracut_hook:12,dracut_hooks_path:12,drawback:6,drive:7,driven:4,driver:[4,12],drop:[8,11],dst:12,due:6,dump:13,dure:[1,2],dyy8gj:13,e083921a7ed1cf2eec91ad12b9ad1e70ef3470b:13,e695affd:13,e6fa6db4:13,each:[1,2,5,6,7,8,12,13],easi:12,easier:[2,6],eastern:8,ec2:6,echo:6,edit:[8,13],edk2:6,effect:8,efi:[6,8,9],efibootmgr:9,either:[6,8,12,13],el7:13,els:[7,12],emit:12,empti:[7,8,12,13],empty_lines_in_valu:13,en_u:8,enabl:[6,7,8,9,12,13],enablerepo:[7,12],encod:12,encount:[6,13],encrypt:8,end:[1,5,6,7,8,12,13],endfor:12,endif:7,endpoint:13,enforc:[6,8,13],enhanc:6,enough:12,ensur:[12,13],enter:13,entir:8,entri:[2,6,8,12,13],env_add:12,env_prun:12,environ:[6,7,8,12],epoch:[2,13],equival:12,err:12,error:[2,5,6,8,10,12],escap:12,especi:8,estim:13,estimate_s:[12,13],etc:[6,7,8,12,13],even:[6,7,13],ever:0,everi:13,everyth:[6,7,12],exact:[8,13],exactli:[8,13],examin:[6,9],exampl:[1,2,6,7,11,12,13],except:[6,7,8,12,13],exclud:12,excludepkg:[7,12],exec:6,execproduct:12,execreadlin:12,execut:[2,4,5,8,9,12],executil:10,execwithcaptur:12,execwithredirect:12,exist:[0,2,4,6,7,8,12,13],exit:[1,2,6,7,8,9,12],expand:12,expans:12,expect:[2,5,6,7,8,9,12,13],expected_kei:13,experi:12,expir:13,expire_sec:13,explicitli:8,explor:1,exract:13,ext4:[1,7,8,12,13],extend:8,extens:[1,7],extern:12,extra:[2,6,8,9,13],extra_boot_arg:[6,12],extract:[12,13],f15:6,f16:6,f5c2918544c4:13,f629b7a948f5:13,fail:[1,2,8,12,13],failur:[12,13],fairli:7,fakednf:12,fall:[7,13],fals:[1,2,5,6,7,8,12,13],far:6,fatal:[6,12],fatalerror:12,fe925c35e795:13,featur:[6,8],fedora:[3,6,7,8,12,13],fedoraproject:[6,7,13],feedback:6,fetch:[0,12],few:[6,7],field:[1,2,8,13],figur:4,fila:13,file:[0,1,2,4,5,7,8,9,11,12,13],fileglob:12,filenam:[0,1,2,12,13],filesystem:[1,8,11,12,13],fill:13,filter:[12,13],filter_stderr:12,find:[0,4,5,6,12,13],find_commit_tag:13,find_field_valu:13,find_free_port:12,find_nam:13,find_ostree_root:12,find_recipe_obj:13,find_templ:12,findkernel:12,fine:8,finish:[1,2,7,8,12,13],firewal:13,firewall_cmd:13,firewalld:8,firmwar:6,first:[1,4,6,7,8,9,12,13],first_registr:13,fit:6,five:2,fix:12,flag:12,flask:13,flask_blueprint:[10,12],flatten:6,flexibl:4,fmt:12,fname:12,fobj:12,follow:[1,2,5,6,12,13],foo:13,forc:[7,8,12,13],form:[0,5,7,9,13],format:[1,2,6,8,12,13],found:[5,6,8,9,12,13],four:2,free:[7,12],freez:[1,2,13],from:[0,1,2,4,5,6,7,8,9,11,12,13],from_commit:13,front:5,frozen:[1,2],frozen_toml_filenam:2,frozenset:13,fs_imag:6,fs_label:6,fsck:12,fsimag:[6,12],fstab:6,fstype:[6,12],ftp:8,ftruncat:12,full:[0,8,9,12,13],further:12,game:13,gather:1,gener:[2,4,6,7,9,12,13],generate_module_data:12,generate_module_info:12,get:[0,5,6,8,12,13],get_all_upload:5,get_arch:12,get_arg:2,get_base_dir:13,get_base_object:13,get_buildarch:12,get_commit_detail:13,get_compose_typ:13,get_default:13,get_default_servic:13,get_dnf_base_object:12,get_extra_pkg:13,get_filenam:0,get_firewall_set:13,get_image_nam:13,get_iso_label:12,get_kernel_append:13,get_keyboard_layout:13,get_languag:13,get_loop_nam:12,get_par:2,get_ref:2,get_repo_descript:13,get_repo_sourc:13,get_revision_from_tag:13,get_servic:13,get_siz:2,get_source_id:13,get_timezone_set:13,get_upload:5,get_url_json:0,get_url_json_unlimit:0,get_url_raw:0,gfile:13,ggit:13,gib:[6,7,12],gid:[8,13],git:[6,13],gitarchivetarbal:13,github:6,gitlock:13,gitrepo:13,gitrpm:[10,12],gitrpmbuild:13,given:[0,5,12,13],glanc:6,glob:[7,8,12,13],glusterf:13,gnome:6,gnu:13,goe:[4,7,12],going:[1,6],gonna:13,good:[6,9,12],googl:[1,8],gpg:[8,13],gpgcheck:8,gpgkei:[8,13],gpgkey_url:[8,13],gplv3:13,graft:12,green:13,group:[1,6,12,13],group_nam:13,group_typ:13,grow:6,growpart:6,grub2:[6,8,9],grub:12,gui:8,gzip:[6,12],had:6,handl:[1,2,6,7,8,12],handle_api_result:2,handler:12,happen:[6,7,12],hard:13,hardlink:12,has:[1,2,5,6,8,11,12,13],hash:[1,2,8,13],hasn:9,have:[1,2,5,6,7,8,9,12,13],haven:6,hawkei:13,hda:1,head:[8,13],head_commit:13,header:[0,8,13],hello:6,help:[0,1,6,7,9,10,12],helper:13,here:[4,6,7,8,9,11,13],higer:13,highbank:6,higher:7,histori:[8,13],hold:13,home:[6,8],homepag:13,hook:12,host:[0,6,7,8,12,13],hostnam:[8,13],how:[4,12],howev:[6,7,8],html:1,http:[0,1,2,6,7,8,12,13],http_client:10,httpconnect:0,httpconnectionpool:0,httpd:8,human:2,hw_random:12,hwmon:12,hybridiso:9,hyper:1,i386:12,ia64:12,iam:1,id_rsa:8,idea:[4,6,9],ideal:12,identifi:[2,7],ids:13,ignor:[5,12],ignore_corrupt:5,ignore_miss:5,imag:[2,3,4,5,7,9,12,13],image_nam:[5,6,8,13],image_path:[5,13],image_s:13,image_size_align:6,image_typ:[6,12],images_dir:12,imap:8,img:[6,7,11,12],img_mount:12,img_siz:12,imgutil:10,immedi:8,immut:[8,13],implantisomd5:12,implement:[1,8,11,12],includ:[0,1,2,5,6,7,8,9,11,13],inclus:13,incom:12,increment:13,indent:2,index:[3,13],indic:12,individu:2,info:[1,2,8,9,13],inform:[1,2,4,5,7,8,13],init:[6,8,12],init_file_log:12,init_stream_log:12,initi:12,initramf:[6,7,12,13],initrd:[6,7,12],initrd_address:12,initrd_path:12,inject:8,inline_comment_prefix:13,input:[6,9,12],input_iso:9,inroot:12,insecur:6,insert:13,insid:[6,12,13],insort_left:13,inst:9,instal:[1,2,4,9,10,11,13],install_log:12,installclass:11,installerror:12,installimg:[11,12],installinitrd:12,installkernel:12,installpkg:[7,11,12,13],installroot:[7,12],installtre:12,installupgradeinitrd:12,instanc:[5,6,13],instead:[1,2,5,6,7,8,13],instroot:4,instruct:6,insuffici:12,integ:13,interact:1,interfac:8,interfer:7,intermedi:1,interpol:13,intrd:12,introduct:3,invalid:[5,13],ioerror:13,is_cancel:5,is_commit_tag:13,is_image_mount:12,is_parent_diff:13,iserror:12,isfin:[7,12],isn:[6,12,13],iso:[1,4,12,13],iso_nam:6,iso_path:12,isoinfo:12,isolabel:12,isolinux:12,isomountpoint:12,issu:8,item:[2,12,13],iter:[12,13],its:[5,6,12,13],itself:8,jboss:13,job:13,job_creat:13,job_finish:13,job_start:13,joinpath:12,json:[0,1,2,6,8,12,13],just:[2,5,11,12,13],kbyte:13,kdir:12,keep:[1,6,12,13],keepglob:12,kei:[1,2,5,8,12,13],kernel:[6,7,9,12,13],kernel_append:13,kernel_arg:[6,12],keyboard:[8,13],keyboard_cmd:13,keymap:8,kib:13,kickstart:[8,12,13],kickstartpars:12,kill:[6,12],knowledg:4,known:2,kpartx:[6,12],kpartx_disk_img:12,ks_path:12,ks_templat:13,ksflatten:6,kubernet:13,kvm:[1,6],kwarg:[12,13],label:[6,12],lambda:12,lane:[1,6,7,8,9],lang:13,lang_cmd:13,languag:[1,8,13],larg:[2,8,13],last:[1,2,9,12,13],later:[12,13],latest:[6,13],launch:8,layout:13,lazi:12,lead:[0,12],least:[6,12],leav:[7,8,12,13],left:[8,12,13],leftmost:13,leftov:[6,12],len:13,less:13,level:[6,7,8,12,13],lib64_arch:12,lib:[5,8,12,13],lib_dir:5,librari:4,libus:13,libvirt:6,licens:13,lift:[1,10],light:7,like:[1,5,6,7,8,9,11,12,13],limit:[0,6,8,12,13],line:[2,4,8,12,13],link:12,linktre:12,linux:[6,7,12],list:[1,2,4,5,6,7,8,12,13],list_branch_fil:13,list_commit:13,list_commit_fil:13,list_provid:5,listen:[1,8,12],live:[1,4,8,12,13],live_image_nam:12,live_rootfs_s:6,livecd:12,livemedia:[3,8,9,12,13],liveo:[7,12],livesi:6,livetemplaterunn:12,lmc:[6,12],lmc_parser:12,load:[5,12,13],load_profil:5,load_set:5,local:[1,6,12,13],localectl:8,localhost:[12,13],locat:[6,7,13],lock:[8,13],lock_check:13,log:[1,2,6,7,12,13],log_check:12,log_error:12,log_output:12,log_path:12,log_request_handler_class:12,log_selinux_st:12,logdir:12,logfil:[1,6,7,8,12],logger:12,logic:7,logmonitor:12,lognam:12,logo:7,logrequesthandl:12,logserv:12,longer:[6,7,8,13],look:[1,4,5,6,8,11,13],loop:[6,7,12],loop_attach:12,loop_detach:12,loop_dev:12,loop_waitfor:12,loopdev:12,loopx:12,loopxpn:12,lorax:[1,2,5,6,9,11,12,13],lorax_composer_pars:13,lorax_pars:12,lorax_templ:6,loraxdir:12,loraxdownloadcallback:12,loraxrpmcallback:12,loraxtempl:12,loraxtemplaterunn:[7,12],lose:6,losetup:12,lost:13,low:12,lowercas:12,lowest:12,lpar:12,lst:[2,13],ltmpl:[7,10],lvm2:12,lzma:[6,12],mac:[6,7,9],macboot:[6,7],machin:9,made:[8,12],mai:[1,6,7,8,9,12,13],mail:6,main:2,maintain:4,make:[1,2,5,6,7,8,9,12,13],make_:8,make_appli:12,make_compos:13,make_disk:8,make_dnf_dir:13,make_git_rpm:13,make_imag:12,make_live_imag:12,make_livecd:12,make_owned_dir:13,make_queue_dir:13,make_runtim:12,make_setup_st:13,make_tar_disk:12,makestamp:4,maketreeinfo:4,mako:[4,6,7,12],manag:[1,5],mandatori:[8,13],mani:13,manpag:[6,7],manual:13,map:2,mark:5,mask:12,master:13,match:[1,6,8,12,13],maximum:13,maxretri:12,mbr:6,meant:[1,5,12,13],meantim:1,mechan:8,media:[6,12],megabyt:6,member:[1,6],memlimit:12,memori:[6,12],memtest86:6,mention:12,messag:[8,9,12,13],metadata:[1,2,6,7,8,12,13],metalink:[8,13],method:[6,8,12,13],mib:[1,6,12,13],mime:13,mind:[6,13],minim:[6,8,12],minimum:[5,6,13],minut:6,mirror:[6,12,13],mirrorlist:[7,8,12,13],mirrormanag:6,miss:[5,12,13],mix:4,mkbtrfsimg:12,mkcpio:12,mkdir:[6,7,12],mkdosimg:12,mkext4img:12,mkf:12,mkfsarg:12,mkfsimag:12,mkfsimage_from_disk:12,mkhfsimg:12,mkisof:9,mkksiso:3,mknod:6,mkqcow2:12,mkqemu_img:12,mkrootfsimg:12,mkspars:12,mksquashf:12,mktar:12,mnt:[8,12],mock:[1,8],mockfil:8,moddir:12,mode:[1,6,7,12,13],modeless:12,modifi:[6,9,12,13],modul:[1,3,4,7,10],module_nam:13,module_nv:13,modules_cmd:2,modules_info:13,modules_list:13,monitor:[6,10,13],more:[1,4,6,8,12],most:[1,2,6,8,13],mount:[6,8,9,10],mount_boot_part_over_root:12,mount_dir:12,mount_ok:12,mountarg:12,mountpoint:[6,12],move:[7,8,12,13],move_compose_result:[8,13],msg:[12,13],much:12,multi:6,multipl:[1,2,6,7,8,9,12,13],multipli:2,must:[1,6,7,8,11,12,13],mvebu:6,myconfig:12,name:[2,5,9,12,13],namespac:2,need:[1,2,6,7,8,9,12,13],neither:13,network:[6,7,8,9,12],never:12,nevra:[2,13],new_image_nam:5,new_item:13,new_recip:13,new_repo_sourc:13,new_set:5,newer:6,newest:[1,2,13],newli:12,newlin:12,newrecipegit:13,newrun:12,next:[12,13],nice:[1,2],noarch:[8,13],node:[6,7],nomacboot:[6,7],non:[7,8,12,13],none:[0,2,5,6,8,12,13],nop:12,norm:2,normal:[1,6,7,9,11],north:8,nosmt:8,nosuchpackag:12,note:[6,7,12,13],noth:[2,12,13],noupgrad:7,noverifi:7,noverifyssl:[7,12],novirt:6,novirt_cancel_check:12,novirt_instal:[8,12,13],now:[6,8,11,12,13],nspawn:[6,7],ntp:8,ntpserver:[8,13],number:[1,2,6,7,8,12,13],numer:8,nvr:7,object:[0,1,5,12,13],observ:6,occas:12,occur:12,oci_config:6,oci_runtim:6,octalmod:12,off:8,offset:[0,13],oid:13,old:[6,7,12,13],old_item:13,old_recip:13,old_vers:13,older:[6,7],omap:6,omit:8,onc:[1,6,7,8,13],one:[1,2,6,7,8,11,12,13],ones:[7,8,12,13],onli:[1,2,6,7,8,9,12,13],onto:7,open:[8,13],open_or_create_repo:13,openh264:13,openssh:8,openstack:[1,8],oper:[4,6,8,13],opt:[2,8,12,13],option:[1,2,4,5,6,7,8,12,13],order:[1,4,7,8,13],org:[1,6,7,8,13],origin:[0,6,8,9,13],osbuild:[1,8],ostre:[1,2,6,8,12],other:[2,4,6,7,8,12,13],otherwis:[7,8,12,13],ouput:13,out:[1,4,8,9,12,13],outfil:12,output:[1,2,6,7,10],output_iso:9,outputdir:[7,12],outroot:12,outsid:12,over:[8,11],overhead:12,overrid:[6,7,8,12,13],overridden:8,overwrit:[1,2,5,8,13],overwritten:12,ovmf:6,ovmf_path:[6,12],own:[6,7,8,13],owner:[8,13],ownership:[8,13],p_dir:13,pacag:12,packag:[1,4,6,7,10,11],package_nam:13,package_nv:13,packagedir:12,packagenevra:2,page:3,param1:0,param2:0,param:[12,13],paramat:11,paramet:[0,2,5,12,13],parent:[1,2,13],pars:[12,13],parser:12,part:[2,6,7,11,12,13],particular:12,partit:[1,6,12],partitin:6,partitionmount:12,pass:[1,2,5,6,7,8,9,11,12,13],passwd:6,password:[6,8,13],pat:12,patch:[8,13],path:[0,1,2,5,6,7,8,9,12,13],pathnam:[9,12],pattern:[5,12],payload:12,pcritic:12,pdebug:12,per:[12,13],permiss:[8,13],perror:12,phys_root:12,physic:12,pick:[1,12],pid:[6,12],pinfo:12,ping:13,pivot:12,pkg:[2,12,13],pkg_to_build:13,pkg_to_dep:13,pkg_to_project:13,pkg_to_project_info:13,pkgglob:12,pkglistdir:12,pkgname:11,pkgsizefil:12,pki:13,place:[1,2,6,7,11,12,13],placehold:[5,13],plai:13,plain:[6,7,8,12,13],plan:9,platform:[6,13],play0ad:13,playbook:[1,5],playbook_path:5,pleas:12,plugin:7,plugin_conf:6,point:[4,6,8,12,13],pool:8,popen:[12,13],popul:[12,13],port:[0,6,7,8,12,13],pos:13,posit:13,possibl:[2,6,8,12,13],post:[0,6,8,12,13],post_url:0,post_url_json:0,post_url_toml:0,postfix:8,postinstal:12,postun:12,potenti:5,powerpc:12,ppc64:12,ppc64le:[11,12],ppc:11,pre:[6,8,9,12,13],precaut:1,preexec_fn:12,prefix:[6,8,12,13],prepar:13,prepare_commit:13,prepend:13,present:[4,6,13],preserv:[9,12],pretti:[8,12],pretty_dict:2,pretty_diff_entri:2,prettycommitdetail:2,preun:12,prevent:[7,13],previou:[8,12,13],previous:[1,4,6],primari:[6,8],primarili:8,print:[1,2,9],privileg:8,probabl:7,problem:[1,4,12,13],proc:12,procedur:12,process:[1,2,4,5,6,7,8,11,12,13],produc:[4,6,8,13],product:[1,3,7,12,13],profil:[2,5,13],program:[1,2,6,7,8,12,13],progress:[0,1,2,12,13],proj:13,proj_to_modul:13,project:[0,1,6,8,10,12],project_info:13,project_nam:13,projects_cmd:2,projects_depsolv:13,projects_depsolve_with_s:13,projects_info:[2,13],projects_list:[2,13],projectserror:13,prompt:9,pronounc:13,properti:[12,13],protocol:8,provid:[0,4,6,7,10,12,13],provider_nam:[5,13],providers_cmd:2,providers_delet:2,providers_info:2,providers_list:2,providers_push:2,providers_sav:2,providers_show:2,providers_templ:2,proxi:[7,8,12,13],pub:[6,7,8],pubkei:6,pull:[4,6,7],pungi:4,purpos:[6,8],push:[1,2],put:[8,11,12,13],pwarn:12,pxe:12,pxeboot:7,pyanaconda:11,pykickstart:[12,13],pylorax:[4,7,8,10,11],pyo:12,python:[4,7,12,13],pythonpath:6,qcow2:[1,6,12],qemu:[1,12],qemu_arg:6,qemu_cmd:12,qemuinstal:12,queri:[0,2],queu:[1,2,13],queue:[2,8,10,12],queue_statu:13,quot:12,race:12,rais:[0,2,5,12,13],raise_err:12,ram:[6,12],random:[6,12],rang:12,rare:12,raw:[0,1,2,6,13],rawhid:[6,7],rdo:6,re_test:12,react:8,read:[4,6,12,13],read_commit:13,read_commit_spec:13,read_recipe_and_id:13,read_recipe_commit:13,readabl:2,readi:[5,12,13],readm:13,ready_upload:5,real:[6,8,12],realli:[6,7,12],reason:[6,12],reboot:8,rebuild:[6,7,12],rebuild_initrd:12,rebuild_initrds_for_l:12,recent:[1,2,13],recip:[10,12],recipe_dict:13,recipe_diff:13,recipe_filenam:13,recipe_from_dict:13,recipe_from_fil:13,recipe_from_toml:13,recipe_kei:13,recipe_nam:13,recipe_path:13,recipe_str:13,recipeerror:13,recipefileerror:13,recipegit:13,recipegroup:13,recipemodul:13,recipepackag:13,recommend:[6,8],record:1,recurs:12,redhat:[1,6,7,8,9],redirect:[6,12],reduc:8,ref:[1,2,8,13],refer:[1,8,9,13],referenc:8,refus:6,regener:9,regex:[5,10,12],region:1,regist:13,register_blueprint:13,rel:12,relat:[7,8,13],releas:[1,2,4,6,7,8,12,13],releasev:[6,8,12,13],relev:13,reli:4,reliabl:6,remain:[2,7,8],remaind:13,rememb:8,remov:[1,2,4,6,7,8,12,13],remove_temp:12,removefrom:[7,12],removekmod:[7,12],removepkg:[7,12],renam:[6,12,13],repl:12,replac:[4,6,7,8,11,12,13],repo1:6,repo2:6,repo:[4,7,12,13],repo_dir:13,repo_file_exist:13,repo_to_k:13,repo_to_sourc:13,repo_url:6,repodata:[6,9,13],repodict:13,repoid:13,report:[6,7,8,13],repositori:[7,8,12,13],repres:5,represent:[5,13],reproduc:13,reqpart:[6,12],request:[0,8,12,13],requir:[1,6,8,12,13],rerun:13,rescu:6,reserv:6,reset:[1,2,5,12,13],reset_handl:12,reset_lang:12,reset_upload:5,resolv:12,resolve_playbook_path:5,resolve_provid:[5,13],resort:12,resource_group:13,respond:8,respons:[0,1,12],rest:[8,12],restart:[8,13],restor:13,result:[0,2,6,7,8,12,13],result_dir:6,resultdir:6,results_dir:[12,13],retain:8,reticul:12,retriev:[8,13],retrysleep:12,retun:13,returncod:12,revert:[1,2,13],revert_fil:13,revert_recip:13,revis:13,revisor:4,revpars:13,rexist:12,rglob:12,rhel7:[3,6,13],rhel8:3,rhel:6,rng:6,roll:13,root:[1,2,4,6,7,8,9,12,13],root_dir:13,rootdir:12,rootf:[6,7,12],rootfs_imag:12,rootfs_siz:7,rootm:6,rootpw:[6,13],roughli:12,round:[12,13],round_to_block:12,rout:[0,8,12],rpm:[4,6,8,12,13],rpmbuild:13,rpmfluff:13,rpmname:[8,13],rpmreleas:[8,13],rpmversion:[8,13],rtype:[2,13],rule:[1,13],run:[1,2,6,8,9,11,12,13],run_creat:12,run_pkg_transact:[7,12],runcmd:[7,12],runcmd_output:12,rundir:12,runner:12,runtim:[6,11,12],runtimebuild:[11,12],runtimeerror:[0,5,12,13],rxxx:13,s390x:12,safe:[8,12],samba:13,same:[1,6,7,8,12,13],sampl:12,satisfi:13,save:[0,1,2,5,7,8,12,13],save_set:5,sbin:[6,12],scene:8,schedul:13,script:[1,4,6,12,13],scriptlet:12,search:[3,7,12,13],second:[6,13],secondari:8,secret:[1,13],section:[1,6,8,12,13],secur:1,see:[1,6,7,8,9,12,13],seem:12,select:[1,2,5,6,7,8,12,13],self:[5,8,12,13],selinux:[6,8,12],semver:[8,13],send:[0,1,5],separ:[2,8,12,13],sequenc:12,serial:5,serializ:5,server:[0,1,2,8,10,12],servic:[1,2,7,12,13],services_cmd:13,set:[1,2,4,5,6,7,8,9,12,13],set_statu:5,setenforc:7,setenv:12,setup:[6,7,8,12,13],setup_log:12,sever:[6,11,13],sha256:6,shallow:12,share:[1,6,7,8,11,12,13],share_dir:[5,13],sharedir:[7,8,12],sharpest:13,shell:8,ship:7,shlex:12,shortnam:12,should:[0,1,6,7,8,12,13],should_exit_now:2,show:[1,2,6,7,8,9,12],show_json:2,shown:1,shutdown:[6,12],sig:13,sig_dfl:12,sig_ign:12,sigint:5,sign:[8,12,13],signal:12,signific:8,similar:[7,8],simpl:[2,7,8],simple_test:12,simplerpmbuild:13,simplest:9,simpli:8,simul:2,sinc:[6,8,13],singl:[2,6,13],singleton:12,site:6,situat:8,size:[1,2,6,7,12,13],skip:[6,7,12,13],skip_brand:12,skip_rul:13,slice:13,slightli:6,slow:6,small:12,smp:6,snake_cas:5,socket:[0,1,2,8],socket_path:[0,2],socketserv:12,softwar:13,solut:6,solv:13,some:[0,1,4,6,7,8,12,13],somebodi:13,someplac:8,someth:[4,6,7,8,12,13],sometim:6,sort:[7,13],sound:[7,12],sourc:[0,1,5,7,9,10,12,13],source_glob:13,source_id:13,source_nam:13,source_path:13,source_ref:13,source_to_repo:13,source_to_repodict:13,sources_add:2,sources_cmd:2,sources_delet:2,sources_info:2,sources_list:2,sourcesdir:13,space:[2,7,8,12,13],sparingli:13,spars:[6,12],speak:[4,7],spec:13,special:[7,13],specif:[1,5,6,7,8,11,12,13],specifi:[0,1,2,5,6,8,12,13],speed:[1,6],spin:6,spline:12,split:12,split_and_expand:12,squashf:[6,12],squashfs_arg:12,squashfs_onli:12,src:[3,6,12],srcdir:12,srcglob:12,srv:8,ssh:[6,8,13],sshd:[6,8],sshkei:13,ssl:[7,12],sslverifi:12,stage2:12,stage:[4,6],standard:[12,13],start:[1,2,5,6,7,8,12,13],start_build:13,start_queue_monitor:13,start_upload_monitor:5,startprogram:12,startup:8,state:[1,5,6,8,12,13],statement:12,statu:[0,5,8,10,12],status_callback:5,status_cmd:2,status_filt:13,stderr:12,stdin:12,stdout:[12,13],step:[4,6,9],stick:[8,9],still:[6,8,12],stop:[6,8],storag:[1,2,6,8,12,13],storage_account_nam:13,storage_contain:13,store:[1,5,6,7,8,12,13],str1:2,str2:2,str:[0,2,5,12,13],strang:6,stream:13,strict:13,strictli:7,string:[0,2,5,8,9,12,13],string_low:12,stuck:6,stuff:6,style:12,sub:12,subclass:13,subdirectori:13,submit:13,submodul:10,submount:12,subpackag:10,subprocess:12,subscription_id:13,subset:13,substitut:[6,7,13],succe:13,success:[1,12,13],successfulli:[1,5],sudo:[6,8],suffix:12,suit:[1,8],suitabl:[12,13],summari:[5,8,13],support:[1,2,4,6,7,9,11,13],supported_typ:13,sure:[1,5,6,7,8,9,12,13],suspect:6,swap:6,symlink:[7,12,13],sys:[2,12],sys_root_dir:12,sysimag:12,syslinux:6,sysroot:12,system:[1,6,7,8,9,12,13],system_sourc:13,systemctl:[7,8,12],systemd:[6,7,8,12],sysutil:10,tag:[1,2,7,8,13],tag_file_commit:13,tag_recipe_commit:13,tail:13,take:[2,6,8,11,12,13],take_limit:13,talk:[0,2],tar:[1,2,8,9,13],tar_disk_nam:6,tar_img:12,tarbal:12,tarfil:[6,12],target:[1,6,7,12],tcp:[8,12],tcpserver:12,tear:13,tegra:6,tell:7,telnet:8,telnetd:8,tempdir:12,templat:[1,2,4,6,8,11,12,13],template_fil:12,templatedir:12,templatefil:12,templaterunn:12,temporari:[1,2,4,6,7,8,9,12,13],tenant:13,termin:[6,12],test:[1,6,8,9,13],test_config:13,test_mod:13,test_templ:13,testmod:[1,2],text:[7,8,13],textiowrapp:12,than:[6,8,12,13],thei:[1,6,7,8,13],thelogg:12,them:[4,7,8,12,13],therefor:8,thi:[0,1,2,5,6,7,8,9,11,12,13],thing:[4,6,12,13],those:[4,11,13],though:[4,13],thread:[5,6,8,12,13],three:[2,8],thu:12,ti_don:12,ti_tot:12,time:[6,7,8,9,11,12,13],timedatectl:8,timeout:[0,6,12],timestamp:[10,12],timestamp_dict:13,timezon:13,timezone_cmd:13,titl:[12,13],tmp:[6,7,8,12,13],tmpdir:[12,13],tmpl:[11,12,13],tmux:8,to_commit:13,token:12,told:[7,13],toml:[0,1,2,5,8,10,12],toml_dict:13,toml_filenam:2,tomldecodeerror:13,tomlerror:13,tool:[1,4,6,7,8,9,13],top:[6,7,8,11,12,13],total:[6,13],total_drpm:12,total_fil:12,total_fn:0,total_s:12,touch:12,trace:12,traceback:12,track:[1,13],trail:13,transact:12,transactionprogress:12,transmogrifi:12,trash:6,treat:[8,12],tree:[4,6,7,11,12,13],treebuild:[10,11,13],treeinfo:[7,10],tri:[1,6,12,13],truckin:12,ts_done:12,ts_total:12,tty1:6,tty3:6,tui:6,tupl:[2,12,13],turn:4,two:[2,5,13],type:[0,1,2,5,6,9,12],typic:12,ucfg:5,udev_escap:12,udp:8,uefi:[7,9],uid:[8,13],umask:12,umount:[6,8,12],uncompress:13,undelet:13,under:[1,6,7,8,12,13],understand:8,undo:[1,2,13],unexpectedli:7,unicodedecodeerror:12,uniqu:[1,13],unit:[8,12],unix:[0,2,8,13],unix_socket:10,unixhttpconnect:0,unixhttpconnectionpool:0,unknown:12,unless:[12,13],unmaintain:4,unmount:[6,12],unneed:[4,7,8,12,13],unpack:4,until:[8,12],untouch:12,unus:[2,6],upd:4,updat:[2,3,5,6,7,8,9,12,13],update_vagrant_metadata:12,upgrad:12,upload:[0,6,8,10,13],upload_cancel:2,upload_cmd:2,upload_delet:2,upload_id:13,upload_info:2,upload_list:2,upload_log:[2,5],upload_pid:5,upload_reset:2,upload_start:2,upload_uuid:13,upstream:13,upstream_vc:13,url:[0,6,7,8,9,12,13],url_prefix:13,urllib3:0,usabl:6,usag:[1,6,7,8,9,12],usb:9,usbutil:12,use:[0,1,2,5,6,7,8,9,12,13],used:[1,2,4,6,7,8,9,12,13],useful:[5,6,12],user:[1,2,7,12,13],user_dracut_arg:12,useradd:8,uses:[5,6,7,8,12,13],using:[1,2,6,7,8,9,11,12,13],usr:[1,6,7,8,11,12,13],usual:[1,6,8,13],utc:[8,13],utf:[8,12],util:[0,6,10,12],uuid:[1,2,5,8,13],uuid_add_upload:13,uuid_cancel:13,uuid_delet:13,uuid_dir:13,uuid_get_upload:13,uuid_imag:13,uuid_info:13,uuid_log:13,uuid_ready_upload:13,uuid_remove_upload:13,uuid_schedule_upload:13,uuid_statu:13,uuid_tar:13,v0_api:13,v0_blueprints_chang:13,v0_blueprints_delet:13,v0_blueprints_delete_workspac:13,v0_blueprints_depsolv:13,v0_blueprints_diff:13,v0_blueprints_freez:13,v0_blueprints_info:13,v0_blueprints_list:13,v0_blueprints_new:13,v0_blueprints_tag:13,v0_blueprints_undo:13,v0_blueprints_workspac:13,v0_compose_cancel:13,v0_compose_delet:13,v0_compose_fail:13,v0_compose_finish:13,v0_compose_imag:13,v0_compose_info:13,v0_compose_log:13,v0_compose_log_tail:13,v0_compose_metadata:13,v0_compose_queu:13,v0_compose_result:13,v0_compose_start:13,v0_compose_statu:13,v0_compose_typ:13,v0_modules_info:13,v0_modules_list:13,v0_projects_depsolv:13,v0_projects_info:13,v0_projects_list:13,v0_projects_source_delet:13,v0_projects_source_info:13,v0_projects_source_list:13,v0_projects_source_new:13,v1_compose_fail:13,v1_compose_finish:13,v1_compose_info:13,v1_compose_queu:13,v1_compose_start:13,v1_compose_statu:13,v1_compose_uploads_delet:13,v1_compose_uploads_schedul:13,v1_projects_source_info:13,v1_projects_source_new:13,v1_providers_delet:13,v1_providers_sav:13,v1_upload_cancel:13,v1_upload_info:13,v1_upload_log:13,v1_upload_provid:13,v1_upload_reset:13,vagrant:12,vagrant_metadata:6,vagrantfil:6,valid:[5,8,12,13],validate_set:5,valu:[2,5,6,8,12,13],valueerror:[5,13],valuetok:12,variabl:[6,7,12,13],variant:12,variou:[12,13],vcpu:[6,12],verbatim:6,veri:6,verifi:[1,7,12],version:[0,1,2,4,6,7,8,12,13],vhd:[1,13],via:[6,7,8],video:12,view:[1,13],view_func:13,virt:[12,13],virt_instal:12,virtio:12,virtio_consol:12,virtio_host:12,virtio_port:12,virtual:[6,12],vmdk:1,vmlinuz:[6,12],vnc:[6,12],volid:[6,7,9,12],volum:[6,7,9],vsphere:1,wai:[1,2,6,7,8,13],wait:[1,12,13],want:[1,6,8,9,13],warfar:13,warn:[12,13],wasn:6,watch:6,web:[6,8],websit:[6,8],weight:7,welcom:6,welder:8,weldr:[1,8,13],well:[6,7,8,9,12,13],were:[5,12,13],what:[0,1,4,5,6,7,8,12,13],whatev:13,wheel:[6,8],when:[1,5,6,7,8,9,12,13],whenev:12,where:[1,6,7,8,12,13],whether:[2,5,12,13],which:[1,2,4,5,6,7,8,11,12,13],whitespac:12,who:6,whole:12,widest:8,widget:8,wildcard:8,winnt:12,wipe:9,with_cor:13,with_rng:6,without:[1,6,7,8,9,13],word:12,work:[12,13],work_dir:12,workdir:[7,12],workflow:4,workspac:[1,2,10,12],workspace_delet:13,workspace_dir:13,workspace_exist:13,workspace_filenam:13,workspace_read:13,workspace_writ:13,workstat:7,world:[6,13],would:[1,6,8,9,11,12],wrapper:13,write:[4,12,13],write_commit:13,write_fil:13,write_ks_group:13,write_ks_root:13,write_ks_us:13,write_timestamp:13,writepkglist:12,writepkgs:12,written:[4,6,8,12],wrong:[2,12],wrote:13,wwood:12,www:13,x86:[7,11,12,13],x86_64:[6,7,9,12,13],xattr:12,xfce:6,xfsprog:12,xml:6,xorrisof:[7,9],xxx:2,xxxx:[1,2,6],xxxxx:6,yield:13,you:[1,6,7,8,9,11,12,13],your:[1,6,7,8,11,13],yourdomain:6,yum:[4,6,8,13],yumbas:13,yumlock:13,zero:[12,13],zerombr:6},titles:["composer package","composer-cli","composer.cli package","Welcome to Lorax's documentation!","Introduction to Lorax","lifted package","livemedia-creator","Lorax","lorax-composer","mkksiso","src","Product and Updates Images","pylorax package","pylorax.api package"],titleterms:{"default":[6,7],"import":8,"new":13,AWS:1,Adding:[8,9,13],The:7,Using:6,add:8,ami:6,anaconda:6,api:13,applianc:6,argument:[1,6,7,8,9],atom:6,base:12,befor:4,bisect:13,blueprint:[1,2,8],boot:[6,9],branch:3,brand:7,build:1,buildstamp:12,checkparam:13,cleanup:7,cli:[1,2],cmdline:[1,2,6,7,8,9,12,13],compos:[0,1,2,8,13],config:[5,13],contain:6,content:[0,2,5,12,13],creat:[6,9],creation:[6,7],creator:[6,12],custom:[7,8],debug:[1,6],decor:12,discinfo:12,disk:[6,8],dnfbase:[12,13],dnfhelper:12,docker:6,document:3,download:1,dracut:[6,7],dvd:[8,9],edit:1,error:13,exampl:8,executil:12,exist:1,file:6,filesystem:[6,7],firewal:8,flask_blueprint:13,git:8,gitrpm:13,group:8,hack:6,help:2,how:[6,7,8,9],http_client:0,imag:[1,6,8,11],imgutil:12,indic:3,initi:6,insid:7,instal:[6,7,8,12],introduct:4,iso:[6,7,8,9],kernel:8,kickstart:[6,9],lift:5,live:6,liveimg:9,livemedia:6,local:8,log:8,lorax:[3,4,7,8],ltmpl:12,mkksiso:9,mock:[6,7],modul:[0,2,5,8,12,13],monitor:[1,12],mount:12,name:[1,6,7,8],note:8,oci:6,open:6,openstack:6,option:9,other:3,output:[8,12,13],packag:[0,2,5,8,9,12,13],partit:8,posit:[1,7,8,9],postinstal:7,problem:6,product:11,profil:1,project:[2,13],provid:[1,2,5],proxi:6,pxe:6,pylorax:[12,13],qemu:6,queue:[5,13],quickstart:[6,7,8],recip:13,regex:13,repo:[6,8,9],repositori:6,requir:7,respons:13,result:1,rout:13,run:7,runtim:7,secur:8,server:13,servic:8,sourc:[2,8],squashf:7,src:10,sshkei:8,statu:[1,2,13],submodul:[0,2,5,12,13],subpackag:[0,12],support:8,sysutil:12,tabl:3,tar:6,templat:7,thing:8,timestamp:13,timezon:8,tmpl:7,toml:13,treebuild:12,treeinfo:12,type:[8,13],uefi:6,unix_socket:0,updat:11,upload:[1,2,5],user:[6,8],util:[2,13],vagrant:6,variant:7,virt:6,welcom:3,work:[6,7,8,9],workspac:13}}) \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 9000845d..40a46d5e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -23,6 +23,7 @@ Contents: Documentation for other Lorax Branches ====================================== +* `Fedora 32 `_ * `Fedora 31 `_ * `Fedora 30 `_ * `Fedora 29 `_ diff --git a/docs/man/.doctrees/composer-cli.doctree b/docs/man/.doctrees/composer-cli.doctree index 420c7698..d22943c0 100644 Binary files a/docs/man/.doctrees/composer-cli.doctree and b/docs/man/.doctrees/composer-cli.doctree differ diff --git a/docs/man/.doctrees/composer.cli.doctree b/docs/man/.doctrees/composer.cli.doctree index 2469827a..174b6a9a 100644 Binary files a/docs/man/.doctrees/composer.cli.doctree and b/docs/man/.doctrees/composer.cli.doctree differ diff --git a/docs/man/.doctrees/composer.doctree b/docs/man/.doctrees/composer.doctree index ee386c33..04cba15a 100644 Binary files a/docs/man/.doctrees/composer.doctree and b/docs/man/.doctrees/composer.doctree differ diff --git a/docs/man/.doctrees/environment.pickle b/docs/man/.doctrees/environment.pickle index c3005cb3..ff808eaa 100644 Binary files a/docs/man/.doctrees/environment.pickle and b/docs/man/.doctrees/environment.pickle differ diff --git a/docs/man/.doctrees/index.doctree b/docs/man/.doctrees/index.doctree index 6286e455..64765177 100644 Binary files a/docs/man/.doctrees/index.doctree and b/docs/man/.doctrees/index.doctree differ diff --git a/docs/man/.doctrees/intro.doctree b/docs/man/.doctrees/intro.doctree index 72b37930..695b417a 100644 Binary files a/docs/man/.doctrees/intro.doctree and b/docs/man/.doctrees/intro.doctree differ diff --git a/docs/man/.doctrees/lifted.doctree b/docs/man/.doctrees/lifted.doctree index 85b4d92f..083c02e8 100644 Binary files a/docs/man/.doctrees/lifted.doctree and b/docs/man/.doctrees/lifted.doctree differ diff --git a/docs/man/.doctrees/livemedia-creator.doctree b/docs/man/.doctrees/livemedia-creator.doctree index 68718276..a44ec5a0 100644 Binary files a/docs/man/.doctrees/livemedia-creator.doctree and b/docs/man/.doctrees/livemedia-creator.doctree differ diff --git a/docs/man/.doctrees/lorax-composer.doctree b/docs/man/.doctrees/lorax-composer.doctree index 34d603c5..8e694ef9 100644 Binary files a/docs/man/.doctrees/lorax-composer.doctree and b/docs/man/.doctrees/lorax-composer.doctree differ diff --git a/docs/man/.doctrees/lorax.doctree b/docs/man/.doctrees/lorax.doctree index 17d77e66..bc096b53 100644 Binary files a/docs/man/.doctrees/lorax.doctree and b/docs/man/.doctrees/lorax.doctree differ diff --git a/docs/man/.doctrees/mkksiso.doctree b/docs/man/.doctrees/mkksiso.doctree index cdf4f894..feb58f97 100644 Binary files a/docs/man/.doctrees/mkksiso.doctree and b/docs/man/.doctrees/mkksiso.doctree differ diff --git a/docs/man/.doctrees/modules.doctree b/docs/man/.doctrees/modules.doctree index d82a043f..25540e66 100644 Binary files a/docs/man/.doctrees/modules.doctree and b/docs/man/.doctrees/modules.doctree differ diff --git a/docs/man/.doctrees/product-images.doctree b/docs/man/.doctrees/product-images.doctree index db6e5144..23e13a77 100644 Binary files a/docs/man/.doctrees/product-images.doctree and b/docs/man/.doctrees/product-images.doctree differ diff --git a/docs/man/.doctrees/pylorax.api.doctree b/docs/man/.doctrees/pylorax.api.doctree index 89b8de61..2d2d5f94 100644 Binary files a/docs/man/.doctrees/pylorax.api.doctree and b/docs/man/.doctrees/pylorax.api.doctree differ diff --git a/docs/man/.doctrees/pylorax.doctree b/docs/man/.doctrees/pylorax.doctree index af098796..e4ed89d3 100644 Binary files a/docs/man/.doctrees/pylorax.doctree and b/docs/man/.doctrees/pylorax.doctree differ diff --git a/docs/man/composer-cli.1 b/docs/man/composer-cli.1 index 12f1833c..9b25c7b8 100644 --- a/docs/man/composer-cli.1 +++ b/docs/man/composer-cli.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "COMPOSER-CLI" "1" "Apr 28, 2020" "33.2" "Lorax" +.TH "COMPOSER-CLI" "1" "Oct 01, 2020" "33.10" "Lorax" .SH NAME composer-cli \- Composer Cmdline Utility Documentation . @@ -36,11 +36,15 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] Brian C. Lane <\fI\%bcl@redhat.com\fP> .UNINDENT .sp -\fBcomposer\-cli\fP is used to interact with the \fBlorax\-composer\fP API server, managing blueprints, exploring available packages, and building new images. +\fBcomposer\-cli\fP is an interactive tool for use with a WELDR API server, +managing blueprints, exploring available packages, and building new images. +\fIlorax\-composer \fP and \fIosbuild\-composer +\fP both implement compatible servers. .sp -It requires \fI\%lorax\-composer\fP to be installed on the -local system, and the user running it needs to be a member of the \fBweldr\fP -group. They do not need to be root, but all of the \fI\%security precautions\fP apply. +It requires the server to be installed on the local system, and the user +running it needs to be a member of the \fBweldr\fP group. They do not need to be +root, but all of the \fI\%security precautions\fP +apply. .SH COMPOSER-CLI CMDLINE ARGUMENTS .sp Lorax Composer commandline tool @@ -50,9 +54,7 @@ Lorax Composer commandline tool .sp .nf .ft C -usage: composer\-cli [\-h] [\-j] [\-s SOCKET] [\-\-log LOG] [\-a APIVER] - [\-\-test TESTMODE] [\-V] - ... +usage: composer\-cli [\-h] [\-j] [\-s SOCKET] [\-\-log LOG] [\-a APIVER] [\-\-test TESTMODE] [\-V] ... .ft P .fi .UNINDENT @@ -96,8 +98,13 @@ Default: False .sp .INDENT 0.0 .TP -.B compose start [ | ] +.B compose start [\-\-size XXXX] [ | ] Start a compose using the selected blueprint and output type. Optionally start an upload. +\-\-size is supported by osbuild\-composer, and is in MiB. +.TP +.B compose start\-ostree [\-\-size XXXX] [\-\-parent PARENT] [\-\-ref REF] [ ] +Start an ostree compose using the selected blueprint and output type. Optionally start an upload. This command +is only supported by osbuild\-composer. \-\-size is in MiB. .TP .B compose types List the supported output types. @@ -291,6 +298,10 @@ by using \fBcomposer\-cli compose start ...\fP or an existing image can be uploa with \fBcomposer\-cli upload start ...\fP\&. In order to access the service you need to pass authentication details to composer\-cli using a TOML file, or reference a previously saved profile. +.sp +\fBlorax\-composer\fP and \fBosbuild\-composer\fP handle this differently, with +\fBosbuild\-composer\fP you can currently only specify upload targets during the +compose process. .SH PROVIDERS .sp Providers are the services providers with Ansible playbook support under @@ -442,6 +453,21 @@ composer\-cli upload start "http\-image" aws\-settings.toml .sp This will output the UUID of the upload, which can then be used to monitor the status in the same way described above. +.SH DEBUGGING +.sp +There are a couple of arguments that can be helpful when debugging problems. +These are only meant for debugging and should not be used to script access to +the API. If you need to do that you can communicate with it directly in the +language of your choice. +.sp +\fB\-\-json\fP will return the server\(aqs response as a nicely formatted json output +instead of printing what the command would usually print. +.sp +\fB\-\-test=1\fP will cause a compose start to start creating an image, and then +end with a failed state. +.sp +\fB\-\-test=2\fP will cause a compose to start and then end with a finished state, +without actually composing anything. .SH AUTHOR Weldr Team .SH COPYRIGHT diff --git a/docs/man/livemedia-creator.1 b/docs/man/livemedia-creator.1 index 3e9cd5b3..69dcee38 100644 --- a/docs/man/livemedia-creator.1 +++ b/docs/man/livemedia-creator.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "LIVEMEDIA-CREATOR" "1" "Apr 28, 2020" "33.2" "Lorax" +.TH "LIVEMEDIA-CREATOR" "1" "Oct 01, 2020" "33.10" "Lorax" .SH NAME livemedia-creator \- Live Media Creator Documentation . @@ -79,34 +79,20 @@ Create Live Install Media .ft C usage: livemedia\-creator [\-h] (\-\-make\-iso | \-\-make\-disk | \-\-make\-fsimage | \-\-make\-appliance | \-\-make\-ami | \-\-make\-tar | \-\-make\-tar\-disk | \-\-make\-pxe\-live | \-\-make\-ostree\-live | \-\-make\-oci | \-\-make\-vagrant) - [\-\-iso ISO] [\-\-iso\-only] [\-\-iso\-name ISO_NAME] - [\-\-ks KS] [\-\-image\-only] [\-\-no\-virt] [\-\-proxy PROXY] - [\-\-anaconda\-arg ANACONDA_ARGS] - [\-\-armplatform ARMPLATFORM] [\-\-location LOCATION] - [\-\-logfile LOGFILE] - [\-\-lorax\-templates LORAX_TEMPLATES] [\-\-tmp TMP] - [\-\-resultdir RESULT_DIR] [\-\-macboot] [\-\-nomacboot] - [\-\-extra\-boot\-args EXTRA_BOOT_ARGS] - [\-\-disk\-image DISK_IMAGE] [\-\-keep\-image] - [\-\-fs\-image FS_IMAGE] [\-\-image\-name IMAGE_NAME] - [\-\-tar\-disk\-name TAR_DISK_NAME] [\-\-fs\-label FS_LABEL] - [\-\-image\-size\-align IMAGE_SIZE_ALIGN] - [\-\-image\-type IMAGE_TYPE] [\-\-qemu\-arg QEMU_ARGS] - [\-\-qcow2] [\-\-qcow2\-arg QEMU_ARGS] - [\-\-compression COMPRESSION] - [\-\-compress\-arg COMPRESS_ARGS] [\-\-app\-name APP_NAME] - [\-\-app\-template APP_TEMPLATE] [\-\-app\-file APP_FILE] - [\-\-ram MEMORY] [\-\-vcpus VCPUS] [\-\-vnc VNC] - [\-\-arch ARCH] [\-\-kernel\-args KERNEL_ARGS] - [\-\-ovmf\-path OVMF_PATH] [\-\-virt\-uefi] [\-\-no\-kvm] - [\-\-with\-rng WITH_RNG] [\-\-dracut\-conf DRACUT_CONF] - [\-\-dracut\-arg DRACUT_ARGS] - [\-\-live\-rootfs\-size LIVE_ROOTFS_SIZE] - [\-\-live\-rootfs\-keep\-size] [\-\-oci\-config OCI_CONFIG] - [\-\-oci\-runtime OCI_RUNTIME] - [\-\-vagrant\-metadata VAGRANT_METADATA] - [\-\-vagrantfile VAGRANTFILE] [\-\-project PROJECT] - [\-\-releasever RELEASEVER] [\-\-volid VOLID] + [\-\-iso ISO] [\-\-iso\-only] [\-\-iso\-name ISO_NAME] [\-\-ks KS] [\-\-image\-only] [\-\-no\-virt] + [\-\-proxy PROXY] [\-\-anaconda\-arg ANACONDA_ARGS] [\-\-armplatform ARMPLATFORM] + [\-\-location LOCATION] [\-\-logfile LOGFILE] [\-\-lorax\-templates LORAX_TEMPLATES] [\-\-tmp TMP] + [\-\-resultdir RESULT_DIR] [\-\-macboot] [\-\-nomacboot] [\-\-extra\-boot\-args EXTRA_BOOT_ARGS] + [\-\-disk\-image DISK_IMAGE] [\-\-keep\-image] [\-\-fs\-image FS_IMAGE] [\-\-image\-name IMAGE_NAME] + [\-\-tar\-disk\-name TAR_DISK_NAME] [\-\-fs\-label FS_LABEL] [\-\-image\-size\-align IMAGE_SIZE_ALIGN] + [\-\-image\-type IMAGE_TYPE] [\-\-qemu\-arg QEMU_ARGS] [\-\-qcow2] [\-\-qcow2\-arg QEMU_ARGS] + [\-\-compression COMPRESSION] [\-\-compress\-arg COMPRESS_ARGS] [\-\-app\-name APP_NAME] + [\-\-app\-template APP_TEMPLATE] [\-\-app\-file APP_FILE] [\-\-ram MEMORY] [\-\-vcpus VCPUS] + [\-\-vnc VNC] [\-\-arch ARCH] [\-\-kernel\-args KERNEL_ARGS] [\-\-ovmf\-path OVMF_PATH] [\-\-virt\-uefi] + [\-\-no\-kvm] [\-\-with\-rng WITH_RNG] [\-\-dracut\-conf DRACUT_CONF] [\-\-dracut\-arg DRACUT_ARGS] + [\-\-live\-rootfs\-size LIVE_ROOTFS_SIZE] [\-\-live\-rootfs\-keep\-size] [\-\-oci\-config OCI_CONFIG] + [\-\-oci\-runtime OCI_RUNTIME] [\-\-vagrant\-metadata VAGRANT_METADATA] + [\-\-vagrantfile VAGRANTFILE] [\-\-project PROJECT] [\-\-releasever RELEASEVER] [\-\-volid VOLID] [\-\-squashfs\-only] [\-\-timeout TIMEOUT] [\-V] .ft P .fi diff --git a/docs/man/lorax-composer.1 b/docs/man/lorax-composer.1 index c1a757ab..9fb4e682 100644 --- a/docs/man/lorax-composer.1 +++ b/docs/man/lorax-composer.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "LORAX-COMPOSER" "1" "Apr 28, 2020" "33.2" "Lorax" +.TH "LORAX-COMPOSER" "1" "Oct 01, 2020" "33.10" "Lorax" .SH NAME lorax-composer \- Lorax Composer Documentation . @@ -36,7 +36,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] Brian C. Lane <\fI\%bcl@redhat.com\fP> .UNINDENT .sp -\fBlorax\-composer\fP is an API server that allows you to build disk images using +\fBlorax\-composer\fP is a WELDR API server that allows you to build disk images using \fI\%Blueprints\fP to describe the package versions to be installed into the image. It is compatible with the Weldr project\(aqs bdcs\-api REST protocol. More information on Weldr can be found \fI\%on the Weldr blog\fP\&. @@ -44,6 +44,17 @@ information on Weldr can be found \fI\%on the Weldr blog\fP\&. Behind the scenes it uses \fI\%livemedia\-creator\fP and \fI\%Anaconda\fP to handle the installation and configuration of the images. +.sp +\fBNOTE:\fP +.INDENT 0.0 +.INDENT 3.5 +\fBlorax\-composer\fP is now deprecated. It is being replaced by the +\fBosbuild\-composer\fP WELDR API server which implements more features (eg. +ostree, image uploads, etc.) You can still use \fBcomposer\-cli\fP and +\fBcockpit\-composer\fP with \fBosbuild\-composer\fP\&. See the documentation or +the \fI\%osbuild website\fP for more information. +.UNINDENT +.UNINDENT .SH IMPORTANT THINGS TO NOTE .INDENT 0.0 .IP \(bu 2 @@ -124,10 +135,8 @@ Lorax Composer API Server .sp .nf .ft C -usage: lorax\-composer [\-h] [\-\-socket SOCKET] [\-\-user USER] [\-\-group GROUP] - [\-\-log LOG] [\-\-mockfiles MOCKFILES] - [\-\-sharedir SHAREDIR] [\-V] [\-c CONFIG] - [\-\-releasever STRING] [\-\-tmp TMP] [\-\-proxy PROXY] +usage: lorax\-composer [\-h] [\-\-socket SOCKET] [\-\-user USER] [\-\-group GROUP] [\-\-log LOG] [\-\-mockfiles MOCKFILES] + [\-\-sharedir SHAREDIR] [\-V] [\-c CONFIG] [\-\-releasever STRING] [\-\-tmp TMP] [\-\-proxy PROXY] [\-\-no\-system\-repos] BLUEPRINTS .ft P diff --git a/docs/man/lorax.1 b/docs/man/lorax.1 index 4ccaf35f..de8e2d53 100644 --- a/docs/man/lorax.1 +++ b/docs/man/lorax.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "LORAX" "1" "Apr 28, 2020" "33.2" "Lorax" +.TH "LORAX" "1" "Oct 01, 2020" "33.10" "Lorax" .SH NAME lorax \- Lorax Documentation . @@ -55,20 +55,14 @@ Create the Anaconda boot.iso .sp .nf .ft C -usage: lorax [\-h] \-p PRODUCT \-v VERSION \-r RELEASE [\-s REPOSITORY] - [\-\-repo REPOSITORY] [\-m REPOSITORY] [\-t VARIANT] [\-b URL] - [\-\-isfinal] [\-c CONFIGFILE] [\-\-proxy HOST] [\-i PACKAGE] - [\-e PACKAGE] [\-\-buildarch ARCH] [\-\-volid VOLID] [\-\-macboot] - [\-\-nomacboot] [\-\-noupgrade] [\-\-logfile LOGFILE] [\-\-tmp TMP] - [\-\-cachedir CACHEDIR] [\-\-workdir WORKDIR] [\-\-force] - [\-\-add\-template ADD_TEMPLATES] - [\-\-add\-template\-var ADD_TEMPLATE_VARS] - [\-\-add\-arch\-template ADD_ARCH_TEMPLATES] - [\-\-add\-arch\-template\-var ADD_ARCH_TEMPLATE_VARS] [\-\-noverify] - [\-\-sharedir SHAREDIR] [\-\-enablerepo [repo]] - [\-\-disablerepo [repo]] [\-\-rootfs\-size ROOTFS_SIZE] - [\-\-noverifyssl] [\-\-dnfplugin DNFPLUGINS] [\-\-squashfs\-only] - [\-\-skip\-branding] [\-\-dracut\-conf DRACUT_CONF] +usage: lorax [\-h] \-p PRODUCT \-v VERSION \-r RELEASE [\-s REPOSITORY] [\-\-repo REPOSITORY] [\-m REPOSITORY] [\-t VARIANT] + [\-b URL] [\-\-isfinal] [\-c CONFIGFILE] [\-\-proxy HOST] [\-i PACKAGE] [\-e PACKAGE] [\-\-buildarch ARCH] + [\-\-volid VOLID] [\-\-macboot] [\-\-nomacboot] [\-\-noupgrade] [\-\-logfile LOGFILE] [\-\-tmp TMP] + [\-\-cachedir CACHEDIR] [\-\-workdir WORKDIR] [\-\-force] [\-\-add\-template ADD_TEMPLATES] + [\-\-add\-template\-var ADD_TEMPLATE_VARS] [\-\-add\-arch\-template ADD_ARCH_TEMPLATES] + [\-\-add\-arch\-template\-var ADD_ARCH_TEMPLATE_VARS] [\-\-noverify] [\-\-sharedir SHAREDIR] + [\-\-enablerepo [repo]] [\-\-disablerepo [repo]] [\-\-rootfs\-size ROOTFS_SIZE] [\-\-noverifyssl] + [\-\-dnfplugin DNFPLUGINS] [\-\-squashfs\-only] [\-\-skip\-branding] [\-\-dracut\-conf DRACUT_CONF] [\-\-dracut\-arg DRACUT_ARGS] [\-V] OUTPUTDIR .ft P diff --git a/docs/man/mkksiso.1 b/docs/man/mkksiso.1 index 99dfccab..e892ff2a 100644 --- a/docs/man/mkksiso.1 +++ b/docs/man/mkksiso.1 @@ -1,6 +1,6 @@ .\" Man page generated from reStructuredText. . -.TH "MKKSISO" "1" "Apr 28, 2020" "33.2" "Lorax" +.TH "MKKSISO" "1" "Oct 01, 2020" "33.10" "Lorax" .SH NAME mkksiso \- Make Kickstart ISO Utility Documentation . @@ -59,17 +59,17 @@ Add a kickstart and files to an iso .B \-h\fP,\fB \-\-help show this help message and exit .TP -.BI \-a \ ADD_PATHS\fP,\fB \ \-\-add \ ADD_PATHS +.BI \-a \ ADD_PATHS\fR,\fB \ \-\-add \ ADD_PATHS File or directory to add to ISO (may be used multiple times) .TP -.BI \-c \ CMDLINE\fP,\fB \ \-\-cmdline \ CMDLINE +.BI \-c \ CMDLINE\fR,\fB \ \-\-cmdline \ CMDLINE Arguments to add to kernel cmdline .TP .B \-\-debug print debugging info .TP -.BI \-V \ VOLID\fP,\fB \ \-\-volid \ VOLID +.BI \-V \ VOLID\fR,\fB \ \-\-volid \ VOLID Set the ISO volume id, defaults to input\(aqs .UNINDENT .UNINDENT diff --git a/docs/pylorax.api.rst b/docs/pylorax.api.rst index 25a05cee..52b10944 100644 --- a/docs/pylorax.api.rst +++ b/docs/pylorax.api.rst @@ -164,7 +164,6 @@ pylorax.api.workspace module :undoc-members: :show-inheritance: - Module contents --------------- diff --git a/docs/pylorax.rst b/docs/pylorax.rst index 2cd84475..13d2907b 100644 --- a/docs/pylorax.rst +++ b/docs/pylorax.rst @@ -5,6 +5,7 @@ Subpackages ----------- .. toctree:: + :maxdepth: 4 pylorax.api @@ -155,7 +156,6 @@ pylorax.treeinfo module :undoc-members: :show-inheritance: - Module contents ---------------